|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Thu Jul 19, 2007 8:55 pm Post subject: how to work with bmp graphics |
|
|
I am trying to write a subroutine that can import for instance a bmp figure into a graphics region. The graphics region is defined according to the size of the image (for instance 800x600). The I need to read each pixel in order to see if it is white or black (the image is in B&W, by the way). If it finds a black point, then put a "1" in a matrix (or a "0" if it is white). In this way I am trying to transform a B&W picture into a binary matrix, so I can take distances from the center of the image or measure the border of the image, etc. I see that there is a subroutine like GET_PIXEL@ that allows to get the colour of the pixel, however, I do not see how can I create a graphics region where I can import, paste or insert the bitmap and then proceed with the identification of the pixels and the transformation to a matrix. Any ideas?
Thanks a lot in advance!
Agustin |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Fri Jul 20, 2007 5:22 pm Post subject: |
|
|
Graphics regions are normally created by using %gr in a winio@ statement. Details can be found in the FTN95 help file under Win32 Platform->ClearWin+->Graphics. |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Tue Jul 24, 2007 2:12 am Post subject: |
|
|
Thank you Paul for your answer. I looked at Clearwin+ and found some hints for importing my bmp file in a window. However, the problem now is that I cannot read the colour of the pixels in my image. This is a short version of my program
___________
Program Imagine
USE MSWIN
implicit none
CHARACTER*50 file
CHARACTER a(3,1024,1024)
INTEGER hres,vres,nb_colours,ier,i,k,control,red,white,black,j,green
integer colour1,colour2,colour3
type coordenate
integer x
integer y
end type coordenate
type(coordenate),dimension(,allocatable :: matrix
file='c:\imagen640.bmp'
CALL set_rgb_colours_default@(1)
CALL get_dib_size@(file,hres,vres,nb_colours,ier)
IF(ier.NE.0.OR.hres.GT.1024.OR.vres.GT.1024) STOP 'TROUBLE: file not found'
CALL get_dib_block@(file,a,1024,1024,0,0,hres,vres,0,0,ier)
IF(ier.NE.0) STOP 'TROUBLE'
allocate(matrix(hres*vres))
k=1
i=winio@('%gr%lw',hres,vres,control)
CALL display_dib_block@(0,0,a,1024,1024,0,0,hres,vres,0,0,ier)
red= get_matched_colour@(RGB@(255,0,0))
black=get_matched_colour@(RGB@(0,0,0))
white=get_matched_colour@(RGB@(255,255,255))
green=get_matched_colour@(RGB@(0,255,0))
! check the bitmap to find the limits of the black figure on a white background
! the limiting point are saved in an array for plotting latter
DO i=1,hres
do j=1,vres
CALL get_rgb_value@(i,j,colour1)
CALL get_rgb_value@(i,j-1,colour2)
CALL get_rgb_value@(i,j+1,colour3)
if(colour1 == black.and.colour2 /= black.and.colour3 ==black) then
matrix(k)%x=i; matrix(k)%y=j
k=k+1
call draw_point@(i,j,red)
elseif(colour1 == black.and.colour2 == black.and.colour3 /= black) then
matrix(k)%x=i; matrix(k)%y=j
k=k+1
call draw_point@(i,j,red)
else
call draw_point@(i,j,green)
endif
END DO
end do
open(87,file='c:\entorno')
do i=1,k
write (87,*) matrix(i)%x, matrix(i)%y
end do
close(87)
!c--- Write the image away to another file
file='c:\temp\junk.bmp'
CALL put_dib_block@(file,a,1024,1024,0,0,hres,vres,24,ier)
END
______
The idea is to sweep the image along the pixels and check if the pixel is black or white and if it is in the border of the figure (i.e. for instance, the pixel at the border should be black but the previous should also be black and the next should be white if you are leaving the figure or the previous should be white and the next black if you are entering into the figure). For this purpose I call the subroutine CALL get_rgb_value@ and change the colour of the pixel to red if I am in the border (just for marking the border). However, what I get is the same whole figure in red instead of black! Am I misunderstanding the meaning of the subroutine CALL get_rgb_value@?. Any clue would be greatly appreciated!!
Thanks a lot!
Agustin |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Jul 24, 2007 7:48 am Post subject: |
|
|
Not sure about this, but I think you might want simply:
red= RGB@(255,0,0)
black=RGB@(0,0,0)
white=RGB@(255,255,255)
green=RGB@(0,255,0)
rather than:
red= get_matched_colour@(RGB@(255,0,0))
black=get_matched_colour@(RGB@(0,0,0))
white=get_matched_colour@(RGB@(255,255,255))
green=get_matched_colour@(RGB@(0,255,0))
and is your input image 24-bit?
Andy |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Tue Jul 24, 2007 1:31 pm Post subject: |
|
|
Thanks Andy!, but the problem persists!. No change with your suggestion. I do not get the contour but the full figure. The figure is B&W and according to Irfanview is has 16.7 million colours and 24 bitsperpixel. I was searching the forums and there is no information about problems with get_rgb_value@, so I guess I am doing something wrong but I do not see where the mistake is!
Agustin |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Jul 24, 2007 1:46 pm Post subject: |
|
|
It's not obvious to me either. I guess you have to resort to debugging. The first thing I would do would be to use a different colour in the first two branches of your IF construct (both use red at the moment, and that's the problem colour).
Have you used SDBG yet?
Andy |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Tue Jul 24, 2007 2:25 pm Post subject: |
|
|
Well, I used the debugger looking for mistakes in the program from the very begining. Now I changed the colour of the second if to green and the figure is still completely red!. When I follow the colour1,2,3 variables, at some point colour1 appears as 13750737 and colour2 and 3 take the value 16777215!!!. If the figure is B&W I would expect only 0 and 255, isn't it?.
Agustin |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Jul 24, 2007 3:44 pm Post subject: |
|
|
So if the figure is still completely red, that tells you that the logic is wrong at the first IF rather than the second. The program "thinks" that every pixel is right hand margin. There's a bug in your double DO loop, because you're trying to access pixels outside the image, but I don't know if that would be the problem - don't think so. As far as colours are concerned, if your image really is B+W but 24 bit, then yes B = 0 but W = 255 + 255x256 + 255x256^2 = 16777215. So it seems your image isn't actually B+W. |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Tue Jul 24, 2007 4:36 pm Post subject: |
|
|
You are right, the logic seems wrong according to the results, but: where the wrong statement is? I do not see where it is. The only problem seems to be a bug in the FNT95 subroutines o a mishandling of the subroutines by me. About the colours I noticed my mistake as soon I posted my previous message: white is 16777215 as you said! However, the get_rgb_value@ subroutine sometimes reports something different from 0 or 16777215. Is the picture only B&W? Imaging software say yes, but...On the other hand, this should not be an issue if one makes the comparison between black and not black. One should at least obtain a contour that would be not perfect but a contour!. I will continue investigating a little more, but it seems that the problem is not easy and probably comes from the compiler itself.
Thanks a lot for your time and suggestions!
Agustin |
|
Back to top |
|
|
brucebowler Guest
|
Posted: Tue Jul 24, 2007 6:05 pm Post subject: Re: |
|
|
aebolzan wrote: | colour1 appears as 13750737
|
that's D1D1D1 in hex, D1 = 209, so those pixels are a dark shade of grey, not black. |
|
Back to top |
|
|
sparge
Joined: 11 Apr 2005 Posts: 371
|
Posted: Tue Jul 24, 2007 6:31 pm Post subject: |
|
|
I don't think the values returned by get_rgb_colour@ are the issue here. The issue is why the program always flows into the first branch of the IF statement. In an earlier post you said:
"When I follow the colour1,2,3 variables, at some point colour1 appears as 13750737 and colour2 and 3 take the value 16777215!!!"
so at that point the program should definitely not flow as it does - two of the three ANDs should be false. Matter of interest, 13750737 = 209 + 209x256 + 209x256^2 which is a light grey.
You've used SDBG, but what compile options did you use? If you compile using /CHECKMATE I imagine you will find the problem - certainly it ought to complain about you trying to access pixels outside the image in your double DO loop, if nothing else. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Tue Jul 24, 2007 7:21 pm Post subject: |
|
|
Here is an example that may contribute to the debate:
Code: | winapp
c---------------------------------------------------------------
integer i,winio@
external fill_func,start_cb
i=winio@('%ww[no_maxminbox]&')
i=winio@('%mn[&Exit]&','EXIT')
i=winio@('%^gr[black,rgb_colours]&',100,250,fill_func)
i=winio@('%sc',start_cb)
end
c---------------------------------------------------------------
integer function start_cb()
include <clearwin.ins>
integer i,w
call set_line_width@(2)
w=RGB@(200,200,200)
call rectangle@(1,1,99,249,w)
do i=50,200,75
call ellipse@(50,i,32,32,w)
enddo
start_cb=1
end
c-------------------------------------------------------------
integer function fill_func()
include <clearwin.ins>
integer x,y,v,r,a,g,w
call get_mouse_info@(x,y,v)
call get_rgb_value@(x,y,v)
r=get_matched_colour@(RGB@(255,0,0))
g=get_matched_colour@(RGB@(0,255,0))
a=get_matched_colour@(RGB@(255,168,0))
w=get_matched_colour@(RGB@(200,200,200))
if(v.eq.0)then
call fill_surface@(x,y,v,r)
elseif(v.eq.r)then
call fill_surface@(x,y,v,a)
elseif(v.eq.a)then
call fill_surface@(x,y,v,g)
else
call fill_to_border@(x,y,0,w)
endif
fill_func=1
end |
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Jul 26, 2007 3:32 am Post subject: |
|
|
I tried your program with a .bmp file i found in windows (bliss.bmp) and it did something !
1) You should be careful with your do loop range.
2) Why don't you see what colour values you are getting from the file, eg include the following in your code.
....
open (98,file='trace')
write (98,*) red, ' red'
write (98,*) black, ' black'
write (98,*) white, ' white'
write (98,*) green, ' green'
!
DO i=0,hres-1
do j=0,vres -1
CALL get_rgb_value@(i,j,colour1)
write (98,*) i,j,colour1
...
Then think about what you want.
I also didn't change the pixel to green, but left it to display what was in the .bmp file.
! else
! call draw_point@(i,j,green)
You may get some clues from this ? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7927 Location: Salford, UK
|
Posted: Thu Jul 26, 2007 8:02 am Post subject: |
|
|
I was hoping my program would give you some clues.
Here are two points that are significant:
1. %gr needs to have [rgb_colours] (there is also a function to do set this).
2. get_matched_colours@ is only needed when you are not using a hi colour resolution.
In theory you should be able to replace the image in my sample code with your bitmap. Then when you click on the bitmap you should get the colour of the pixel at that point on the screen. |
|
Back to top |
|
|
aebolzan
Joined: 06 Jul 2007 Posts: 229 Location: La Plata, Argentina
|
Posted: Thu Jul 26, 2007 9:05 pm Post subject: |
|
|
Well, thanks a lot for all the comments and suggestions. I have added the suggestions of Paul ([rgb_colours] and removed get_matched_colour and put white=rgb@(255,255,255) instead,etc) and that of John. Yes! the figure is not purely b&W!!! I found that some pixels are quite different from that! In some cases the value is -1! (what colour is this?). Now the program gets almost all the contour, except of course where the colour is different from B&W, and when the contour is a straight line that is parallel to the x axis. This is reasonable because all the points in the column are black!. I think that this problem can be overcome by reading first a double do loop i,j and then a do double loop j,i, so I can cover the figure in two directions and avoid any problem of "paralelism" with respecto to the reading direction. What I did not get is how to insert the figure in the graphic window and read the pixels or colours using Paul's program (as he suggested), but I guess I should read more deeply the manuals!
Now I will try the program with some figures. Hope all will run fine!
Best wishes,
Agustin
P.D. by the way, when the point is inside the contour, I cannot change the colour from black to white using draw_point@(i,j,white) (or green as posted in a preliminary message). Why? Who knows!. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|