Page 1 of 2
Difficult (for me) image processing problem
Posted: 2009-07-08T09:31:14-07:00
by pitosalas
Hi again
Please take a quick look at:
http://www.salas.com/elect/hollow_marks.gif
Notice along the left side, a series of 7 rectangular shapes.
1) I need them all to be fully black, filled in in other words. I've tried numerous combinations of morphological opens, closes, dilates and erodes, and none of them works. They either don't make the shape fully black or they grow the shapes into the edges.
2) Why do I need to make them black? What I really need is the Y position of the centerline of each of the rectangles so I can draw lines left to right that line up with them. The technique I am using, which is to grab a 1 pixel wide column of pixels and then walk it looking for alternating sections of black and white of reasonable length, won't work when the rectangles are sometimes not filled in.
I would greatly appreciate a suggestion on how pursue improving #1, and/or ideas for other ways of achieving #2 that don't break with the kind of distortion that I am seeing.
Thanks much!
Pito
Re: Difficult (for me) image processing problem
Posted: 2009-07-08T12:16:58-07:00
by fmw42
crop out a section that just contains the boxes. then average it down to one column, negate and threshold. then plot the image and it will be just black for the spaces and white for where the boxes are located.
See my script profile or Anthony's im_profile to make the graph.
convert hollow_marks.gif[66x512+8+0] -scale 1x512! -negate -threshold 0 hollow_marks3.gif
profile -c 0 -f 1 -l off hollow_marks3.gif hollow_marks3_profile.gif
the profile looks as follows (the script plots a column as a row chart)
Re: Difficult (for me) image processing problem
Posted: 2009-07-08T12:45:19-07:00
by pitosalas
Fantastic! Thanks.
One question, I am getting a 2 pixel wide result rather than 2. As I tear apart the command,
> convert 'hollow_marks.gif[66x512+8+0]' hm1.gif
gives me an image of the same dimensions, but the sections larger than 66x512 are black. This was odd, but ok. Then:
> convert hollow_marks.gif[66x512+8+0] -scale 1x512! hms.gif
gives me a 2 column wide image. That's quite puzzling.
Could you clarify? (Also was this a difficult or trivial problem?)
Thanks a LOT!
- Pito
Re: Difficult (for me) image processing problem
Posted: 2009-07-08T15:08:54-07:00
by fmw42
try
convert 'hollow_marks.gif[66x512+8+0]' -scale 1x512\! hms.gif
or
convert 'hollow_marks.gif[66x512+8+0]' -scale '1x512!' hms.gif
various systems deal with ! differently. The ! is needed to force it to 1 pixel wide, but if it is left off or not recognized then the result may not be 1 pixel.
Your version of IM may be buggy. What version are you using?
The problem was rather easy for me as I had done similar things in other scripts of mine. The main thing is that you need a subsection that skips the black on the very left edge so that there are relatively white areas between your boxes. If there are a few odd spots or the picture is not quite white, then just raise the threshold value from 0. As long as the boxes have rather black areas for their borders, filled or not, and are separated by relatively clean white areas, averaging and thresholding should isolate them fairly well.
Re: Difficult (for me) image processing problem
Posted: 2009-07-08T15:14:18-07:00
by pitosalas
Thanks!
My version:
Version: ImageMagick 6.5.1-0 2009-04-24 Q16
http://www.imagemagick.org
Copyright: Copyright (C) 1999-2009 ImageMagick Studio LLC
-- Pito
Re: Difficult (for me) image processing problem
Posted: 2009-07-08T16:58:24-07:00
by fmw42
Did either of my suggestions work for you.
I am running on IM 6.5.4-3beta Q16 Mac OSX Tiger
Re: Difficult (for me) image processing problem
Posted: 2009-07-09T15:51:03-07:00
by pitosalas
Neither worked:
/mydev/morphexperiment$ convert 'hollow_marks.gif[66x512+8+0]' -scale '1x512!' hms.gif
/mydev/morphexperiment$ identify hms.gif
hms.gif GIF 1x512 2x512+0+0 8-bit PseudoClass 64c 358b
and
/mydev/morphexperiment$ convert 'hollow_marks.gif[66x512+8+0]' -scale 1x512\! hms.gif
/mydev/morphexperiment$ identify hms.gif
hms.gif GIF 1x512 2x512+0+0 8-bit PseudoClass 64c 358b
Weird, eh? But notice the 1x512 and the 2x512 right after it. Is that a clue?
Re: Difficult (for me) image processing problem
Posted: 2009-07-09T17:21:16-07:00
by fmw42
The two is from the virtual canvas apparently from your input, so add +repage (before or) after -scale 1x512\!
If you don't need the virtual canvas, remove it from any processing that you did beforehand by adding +repage before the output.
Re: Difficult (for me) image processing problem
Posted: 2009-07-09T18:39:38-07:00
by pitosalas
Hm, don't even know what a virtual canvas is. Need to go study
Re: Difficult (for me) image processing problem
Posted: 2009-07-09T19:44:03-07:00
by fmw42
Re: Difficult (for me) image processing problem
Posted: 2009-07-10T08:31:01-07:00
by pitosalas
Thanks.
This might help with something I was looking for.
Right now, as I analyze the image, I am stripping off bits of it along each edge to get rid of artifacts of the scanner where it scanned an area larger than the piece of paper (bleed.) In each case I am doing an 'excerpt' operation to crop the image down. This operation is kind of slow and I realize that really what I am doing is changing the coordinate system that I work with as well as the width and the height of the area I work with and I don't really care about the fact that the image is actually shrunk. So, I could do very careful math on the coordinates that I am using to account for the changed coordinate system and not move any image bits around at all, presumably speeding up considerably. But it's a delicate and error prone change to my code so I've set it aside for now.
Could virtual coordinate systems (or views) be what I should be looking at for that?
Thanks,
Pito
Re: Difficult (for me) image processing problem
Posted: 2009-07-10T09:58:41-07:00
by fmw42
Are you using IM to do the cropping?
I don't know what 'excerpt' operation is? So I don't know if I can help.
It sounds like you are using some other imaging tool to do this and that could be leaving the virtual canvas around. I am not sure why you would want the virtual canvas of the original uncropped image after you crop, but that is likely what is happening. So IM still sees that virtual canvas. The best thing is to strip it off using +repage right after reading your image into IM.
If this is not a correct description then perhaps you could explain in more detail what tools you are using to do what steps of your processing and more about your objectives.
Re: Difficult (for me) image processing problem
Posted: 2009-07-10T11:44:25-07:00
by pitosalas
Yes I am using IM, but via RMagick, the Ruby binding. So it's through the IM API. It looks like the IM API call is called ExcerptImage. (I have attached the C code below in case you are interested.) But it does the 'same' as a crop but faster.
The generic way to ask my question is this... I am cropping an image, but never writing it out. I just crop it and then do further IM operations on the cropped result, including additional cropping. But in the end all I do is examine pixels.
-- Pito
In case you're interested, here's the actual C code that implements 'excerpt' within RMagick...
/*
Method: Image#excerpt(x, y, width, height)
Purpose: lightweight crop
Notes: christy says "does not respect the virtual page offset (-page) and does
not update the page offset and its more efficient than cropping."
*/
static VALUE
excerpt(int bang, VALUE self, VALUE x, VALUE y, VALUE width, VALUE height)
{
#if defined(HAVE_EXCERPTIMAGE)
Image *image, *new_image;
RectangleInfo rect;
ExceptionInfo exception;
memset(&rect,'\0', sizeof(rect));
rect.x = NUM2LONG(x);
rect.y = NUM2LONG(y);
rect.width = NUM2ULONG(width);
rect.height = NUM2ULONG(height);
Data_Get_Struct(self, Image, image);
GetExceptionInfo(&exception);
new_image = ExcerptImage(image, &rect, &exception);
rm_check_exception(&exception, new_image, DestroyOnError);
DestroyExceptionInfo(&exception);
rm_ensure_result(new_image);
if (bang)
{
UPDATE_DATA_PTR(self, new_image);
(void) rm_image_destroy(image);
return self;
}
return rm_image_new(new_image);
#else
bang = bang; self = self;
x = x; y = y;
width = width; height = height;
rm_not_implemented();
return(VALUE)0;
#endif
}
Re: Difficult (for me) image processing problem
Posted: 2009-07-10T13:22:27-07:00
by fmw42
find the equivalent of +repage in RMagick and add it to your crop command
Re: Difficult (for me) image processing problem
Posted: 2009-07-10T17:02:21-07:00
by rmagick
In RMagick you can get the effect of +repage by adding true as the last argument to #crop, or by setting the page= attribute to a rectangle object having 0 for the x, y, width, and height attributes.
img.page= Rectangle.new(0,0,0,0)
For RMagick-specific questions you can usually reach me at
rmagick@rubyforge.org.