Page 1 of 1

Analyze image and fill match with neighboring color

Posted: 2008-04-28T10:47:58-07:00
by bigtable
Looking for some ideas for the following:

Analyze image pixel by pixel looking for white. If white pixel found, fill with neighboring color.

I wrote a script that parses the text output from convert and accomplishes what I outlined above. However, as you might imagine, it is very slow to analyze a large image.

My next attempt at this will be to look at the API to hopefully gain speed and/or write the script to keep track of where the last fill happened start parsing there...

But I was wondering if there would be a way to accomplish the same with convert's FX or other method?

Here's the Perl code that I'm using, approximately:

Code: Select all

&fill;
sub fill {
        open(EXE,"convert pre.png txt:- |");
        while(<EXE>) {
          chomp;
          # 11,0: (48830,48830,48830,    0)  #BEBEBEBEBEBE  grey
          $_ =~ /(.*?):/;
          $coords = $1;
          $_ =~ /\#(.*?)\s+(.*)/;
          $color = $2;
          $color =~ s/\s+//g;

          if ($color =~ /white/i) {
            `convert -fuzz 10% -fill '$last_color' -draw 'color $coords floodfill' pre.png tmp.png`;
            `mv tmp.png pre.png`;
            close(EXE);
            &fill;
          }
          else {
            $last_color = $color;
          }
        }
}
Example image:
NOTE: the example image has a white background. I want to look at just the white in the object so I fill at pixel 1,1 with grey or some other color and then change it back to white after the loop.
Image

Re: Analyze image and fill match with neighboring color

Posted: 2008-04-28T11:09:46-07:00
by magick
Your algorithm is similar to median-filtering:
  • convert example.png -median 2x0.5 umbrella.png

Re: Analyze image and fill match with neighboring color

Posted: 2008-04-28T11:38:33-07:00
by fmw42
Use median filtering (or something like it, e.g. morphological operator), BUT create a mask first that separates the white pixels from the rest. Then composite the median filtered result with the unfiltered result using the mask, so that the non-white pixels are not filtered and the white pixels are replaced by their neighborhood median. Of course this will have trouble if white pixels are neighbors and you will have to increase the size of the radius for the median for the largest white blob area.

Re: Analyze image and fill match with neighboring color

Posted: 2008-04-28T12:23:11-07:00
by bigtable
fmw42 wrote:Use median filtering (or something like it, e.g. morphological operator), BUT create a mask first that separates the white pixels from the rest. Then composite the median filtered result with the unfiltered result using the mask, so that the non-white pixels are not filtered and the white pixels are replaced by their neighborhood median. Of course this will have trouble if white pixels are neighbors and you will have to increase the size of the radius for the median for the largest white blob area.
Ahhh, yes, I see what you're saying and I think I know how to do that.

One potential problem I have is that I'm going to be processing thousands of images like this and the size of the white blob areas will vary -- just how much I don't know.

So... one idea might be to run the morphological operator, test for remaining white space and keep trying until it is gone.

Thanks for the ideas! If anyone else has anything to add please do! :-)

Best regards

Re: Analyze image and fill match with neighboring color

Posted: 2008-04-28T13:43:52-07:00
by fmw42
you can find my morphology script at http://www.fmwconcepts.com/imagemagick/index.html That might help. You can "borrow" any code you want from it and it allows iteration. I don't know if that will be better than the median or not.

Re: Analyze image and fill match with neighboring color

Posted: 2008-05-26T17:13:34-07:00
by anthony
Something that you may not realise.

If you -blur an image using a -channel RGBA setting, then the color in any fully transparent areas surrounding the image will become equal to the average color of the surrounding real image colors!

That means if you make the background areas of your image fully-transparent, then create a lightly blurred copy and overlay the original image. The colors in the areas surrounding the image will be a continuation of the actual images color.

If you then apply a enlarged 'morphology' mask (from Fred's script) of the transparent areas, you can effectively add a one pixel border which is the average of neighboring edge colors of the image.

Of course a morphology mask is a pure on/off mask. you may like to look at smoothing that mask using the new techniques found in IM examples, "Transforming Images", "Edge outline from bitmap masks..
http://imagemagick.org/Usage/transform/#edge_bitmap