Select largest connected nonwhite area

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
Jörn
Posts: 4
Joined: 2013-09-18T10:41:50-07:00
Authentication code: 6789

Select largest connected nonwhite area

Post by Jörn »

Hello,

I would like to use IM (or gimp) in batch mode to process an png file in the following way:

- select the largest nonwhite area
- create an rectangle which contains this area and crop to it
- add a border around (I know how to do this step :-) )

Image
Image
Image

Is there anybody who has an idea how to do it?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Select largest connected nonwhite area

Post by fmw42 »

what platform and what version of IM?

If on unix, you can

1) convert everything that is not white to black and negate (invert) the image so white becomes black and black becomes white. This will create a mask image. (convert image -fuzz XX% -fill black +opaque white -negate result)

2) Use my script, separate, at the link below to get all white areas with their trim canvas size and locations

3) Get the image with the largest white area ( you can test each to compute the white count and find the one with the largest count).
convert image -format "%[fx:mean*w*h]" info:

4) Use that image as a mask with your color image to select only the main large red blocks
convert image mask -compose multiply -composite result

5) trim further if needed (-trim) and add a border (-bordercolor white -border X)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Select largest connected nonwhite area

Post by fmw42 »

If you can identify some point in the largest region, then this will work and is much simpler

coords="260,260"
# first line: read original and create a fully white image the same size
# second line: clone the input and replace everything that is not white with black
# third line: floodfill the large black area with red
# fourth line: replace white with black and red with white and reverse the polarity to create a mask image
# fifth line: composite the original, the white image using the mask, trim and add white border
convert original.png \( -clone 0 -fill white -colorize 100 \) \
\( -clone 0 -fuzz 1% -fill black +opaque white \
-fill red -draw "color $coords floodfill" -alpha off \
-fill black -opaque white -fill white -opaque red -negate \) \
-compose over -composite -trim +repage -bordercolor white -border 10 result.png

If on Windows, replace the line end \ with ^, remove all other \, replace % with %%

See http://www.imagemagick.org/Usage/windows/
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Select largest connected nonwhite area

Post by snibgo »

We can find a point in the largest area with morphology, though it uses an unusual definition of "largest": the area with a pixel furthest from any of its edges. Windows script:

Code: Select all

convert ^
  original2.png ^
  -depth 16 ^
  -fill black +opaque white -negate ^
  -negate -write r0.png -negate ^
  -morphology Distance Euclidean:4 ^
  -auto-level ^
  -threshold 65534 ^
  -write r1.png ^
  -mask r0.png -morphology Dilate:-1 rectangle ^
  +mask ^
  -format %%@ info:
The output (236x409+143+36) is the required crop.
snibgo's IM pages: im.snibgo.com
Jörn
Posts: 4
Joined: 2013-09-18T10:41:50-07:00
Authentication code: 6789

Re: Select largest connected nonwhite area

Post by Jörn »

snibgo wrote:We can find a point in the largest area with morphology, though it uses an unusual definition of "largest": the area with a pixel furthest from any of its edges. Windows script:
Thanks so much for the fast answer.

I should have told you that I'm using version 6.5.4 on linux. My customer probably uses an even older version :-(
So the "-morphology" doesn't work.
Jörn
Posts: 4
Joined: 2013-09-18T10:41:50-07:00
Authentication code: 6789

Re: Select largest connected nonwhite area

Post by Jörn »

fmw42 wrote:If you can identify some point in the largest region, then this will work and is much simpler

coords="260,260"
# first line: read original and create a fully white image the same size
# second line: clone the input and replace everything that is not white with black
# third line: floodfill the large black area with red
# fourth line: replace white with black and red with white and reverse the polarity to create a mask image
# fifth line: composite the original, the white image using the mask, trim and add white border
convert original.png \( -clone 0 -fill white -colorize 100 \) \
\( -clone 0 -fuzz 1% -fill black +opaque white \
-fill red -draw "color $coords floodfill" -alpha off \
-fill black -opaque white -fill white -opaque red -negate \) \
-compose over -composite -trim +repage -bordercolor white -border 10 result.png

If on Windows, replace the line end \ with ^, remove all other \, replace % with %%

See http://www.imagemagick.org/Usage/windows/
Thanks for that help.
I think that I can use this script with the center of the image as starting point.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Select largest connected nonwhite area

Post by fmw42 »

snibgo wrote:We can find a point in the largest area with morphology, though it uses an unusual definition of "largest": the area with a pixel furthest from any of its edges. Windows script:

Code: Select all

convert ^
  original2.png ^
  -depth 16 ^
  -fill black +opaque white -negate ^
  -negate -write r0.png -negate ^
  -morphology Distance Euclidean:4 ^
  -auto-level ^
  -threshold 65534 ^
  -write r1.png ^
  -mask r0.png -morphology Dilate:-1 rectangle ^
  +mask ^
  -format %%@ info:
The output (236x409+143+36) is the required crop.


Very clever.

But I think you can remove two -negates and use mpr to avoid saving files to disk. This seems to work for me (in unix notation). However, it is automated, but takes some time to do the dilate:-1


convert \
original.png \
-depth 16 \
-fill black +opaque white -write show: \
-write mpr:mask -negate -write show: \
-morphology Distance Euclidean:4 \
-auto-level -write show: \
-threshold 65534 -write show: \
-mask mpr:mask -morphology Dilate:-1 rectangle \
+mask -write show: \
-format "%@" info:
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Select largest connected nonwhite area

Post by fmw42 »

Jörn wrote:
Thanks for that help.
I think that I can use this script with the center of the image as starting point.

You can test if the center is not white. If it is search some number of pixels up, down, left, and right. You can iterate the distance until you find a non-white point near the center.

Another way is to make the mask, then average the image down to 1 row and again from the mask down to one column. You can then find some pixel near the middle of the longest white areas that overlaps in both the row and column image.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Select largest connected nonwhite area

Post by snibgo »

fmw42 wrote:But I think you can remove two -negates and use mpr to avoid saving files to disk.
True. My script contained "-negate -negate", which is about as pointless as possible. And I remember thinking "I'll use mpr when I've got it working", but never got around to it.
snibgo's IM pages: im.snibgo.com
Jörn
Posts: 4
Joined: 2013-09-18T10:41:50-07:00
Authentication code: 6789

Re: Select largest connected nonwhite area

Post by Jörn »

fmw42 wrote: You can test if the center is not white. If it is search some number of pixels up, down, left, and right. You can iterate the distance until you find a non-white point near the center.
It is probably not the smartest way of doing it but it works very well:

Code: Select all

#!/usr/bin/perl

my $file = "original.png";

my ($size_x, $size_y, $x_offset, $y_offset) = (`identify $file` =~ /.*?([\d]+)x([\d]+)\+([\d]+)\+([\d]+)/);

my ($point, $offset);

for (my $i = 0.3;$i <= 0.7; $i += 0.1) {

  $point  = sprintf ("%d,%d" , $size_x*$i , $size_y*$i);
  $offset = sprintf ("%d+%d" , $size_x*$i , $size_y*$i);
 
  my $color = `convert ${file}[1x1+$offset] -format "%[fx:floor(255*u.r)],%[fx:floor(255*u.g)],%[fx:floor(255*u.b)]" info:`;
  my ($r, $g, $b) = ($color =~ /([\d]+),([\d]+),([\d]+)/);

  print "Point = $point und $i\n";
  print "RGB = $r $g $b\n";

  last if ($r < 255 or $g < 255 or $b < 255);

}

system("convert $file \\
        -trim +repage \\
        \\( -clone 0 -fill white -colorize 100 \\) \\
        \\( -clone 0 -fuzz 1% -fill black +opaque white \\
        -fill red -draw \"color $point floodfill\" -alpha off \\
        -fill black -opaque white -fill white -opaque red -negate \\) \\
        -compose over -composite -trim +repage \\
        -bordercolor white -border 25 x:");
Haxton Fale
Posts: 2
Joined: 2013-09-21T03:26:18-07:00
Authentication code: 6789

Re: Select largest connected nonwhite area

Post by Haxton Fale »

Hello,
I hope you don't mind if I join in, since I have a very similar problem - I need to get rid of the largest black area and replace it with 100% transparency, and I know the (0,0) pixel belongs to it. I know I should extrapolate the correct script/command (I need this on Windows CLI) from your replies, but I don't really have the time for that (sorry!) and I'd really appreciate it if someone helped me write it!
As an added bonus, my input is in BMP and the output is in PNG :) so filenames (sans extensions) can overlap.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Select largest connected nonwhite area

Post by snibgo »

Code: Select all

convert in.bmp -fill None -floodfill +0+0 Black out.png
snibgo's IM pages: im.snibgo.com
Haxton Fale
Posts: 2
Joined: 2013-09-21T03:26:18-07:00
Authentication code: 6789

Re: Select largest connected nonwhite area

Post by Haxton Fale »

Yes, that's it, thank you very much!
I'm new to ImageMagick and haven't had much chance to play around, or even read the help pages properly. Thank you nonetheless!
Post Reply