Page 1 of 1

Find unused/blank area in an image

Posted: 2016-04-24T14:33:32-07:00
by troydsmith
Hello,

I'm trying to automatically place a caption over an image, but want to place the caption in an area that is unused/blank. I know the background color of the image and was wondering if determining the unused/blank area in an image is possible with ImageMagick. Ideally, I'd get the co-ordinates of the largest unused rectangle and then determine if the caption can fit within the rectangle. I will already know the dimensions of the caption before starting the analysis and could use this information if helpful. The caption can be either another image or can be text. I plan on placing the caption using either ImageMagick or a .pdf generation tool.

I'm using ImageMagick 6.9.0-0 Q16 x86_64. I've been using the command line tools rather than an API.

As an example, in the image below the unused/blank area identified would be to the left of the sun.
https://www.dropbox.com/s/yoc236hdh2714 ... g.jpg?dl=0

I'd greatly appreciate any advice/suggestions. Thanks!

Re: Find unused/blank area in an image

Posted: 2016-04-24T14:49:34-07:00
by snibgo
I assume you won't use inputs that have been through JPEG compression.

As you know the background colour (in your example, white) you can turn all the other pixels black ("-fill Black +opaque White"), then use a procedure such as my innerTrim.bat script (see my "Inner Trim" page). I think Fred has a related script for bash.

If you didn't know the background colour, you could use "-connected-components" to find it.

Re: Find unused/blank area in an image

Posted: 2016-04-24T15:57:53-07:00
by fmw42
My scripts, autocaption and autolabel, will find the most homogenous of a user specified size region and place your text there. They work only on Unix systems. You do not say what your platform is! If appropriate, see my link below.

Otherwise, create a template image of the desired size and color of your "empty" background region and use the compare function to locate the closest matching subsection of the larger image. See

http://www.imagemagick.org/script/compare.php
http://www.imagemagick.org/Usage/compare/

As snibgo has said, you can also threshold your image to binary (background color and non-background color), then use -connected-components to find the coordinates of the largest bounding box of the background color. See http://www.imagemagick.org/script/conne ... onents.php

Re: Find unused/blank area in an image

Posted: 2016-04-25T15:10:51-07:00
by troydsmith
Thanks the replies. I'm on a linux based system.

I'm looking at the -connected-components solutions and so far so good. The one item comment that I can't seem to easily get is the "coordinate of the largest bounding box of the background color." So far no matter what input image I use, I get the coordinates of the components themselves rather than the coordinates corresponding to the background color. I realize I could write an algorithm to that would identify a rectangle but am hoping to avoid this if possible.

Here are the commands that I've ran starting with the attached image in my original message.

convert ~/Desktop/drawing.jpg -fill Black +opaque White ~/Desktop/drawingB.png

convert ~/Desktop/drawingB.png -colorspace gray -negate -define connected-components:verbose=true -define connected-components:area-threshold=250 -connected-components 8 -auto-level ~/Desktop/drawingA.jpg
Objects (id: bounding-box centroid area mean-color):
0: 470x89+0+0 204.4,41.6 36059 srgb(0,0,0)
1: 236x89+352+0 476.1,54.0 13141 srgb(250,250,250)
2: 114x89+496+0 570.7,35.0 5090 srgb(1,1,1)

I then try and negate the original b/w image.

convert ~/Desktop/drawingB.png -negate ~/Desktop/drawingB2.png

convert ~/Desktop/drawingB2.png -colorspace gray -negate -define connected-components:verbose=true -define connected-components:area-threshold=250 -connected-components 8 -auto-level ~/Desktop/drawingA.jpg
Objects (id: bounding-box centroid area mean-color):
0: 470x89+0+0 204.4,41.6 36059 gray(255)
1: 236x89+352+0 476.1,54.0 13141 gray(5)
2: 114x89+496+0 570.7,35.0 5090 gray(254)


So I'm still ending up with the boundaries around the identified blobs.

Is there a way to force the background color for the connected-components algorithm such that the background color is treated as a blob?

Re: Find unused/blank area in an image

Posted: 2016-04-25T15:42:03-07:00
by snibgo
troydsmith wrote:The one item comment that I can't seem to easily get is the "coordinate of the largest bounding box of the background color."
I don't know why you want the bounding box of the background colour.

If you do want this, for some reason, then first define what the "background colour" is. In this example, it isn't white.

Re: Find unused/blank area in an image

Posted: 2016-04-25T15:53:47-07:00
by fmw42
If your image has any border of background color (black?) and no foreground color (white?) touches the edges of the image, then the bounding box of the background color is the whole image. It is a blob, but has holes in it of the foreground color, which themselves may have holes of background color. But typically the largest background color region will be "blob" id=0.

As snibgo asked, why do you want that region?

Re: Find unused/blank area in an image

Posted: 2016-04-25T17:38:03-07:00
by troydsmith
That's not the region I want. I want the largest or close to the largest area of unused/blank area. In other words the largest bounding box of the background color that does not include any other blog. The blobs returned by connected-components does not provide this region expressly.

In Fred's first comment above he states "then use -connected-components to find the coordinates of the largest bounding box of the background color." How do I do this? Blob 0 isn't this as it is the entire image. And all of the other blobs contain a non-background color.

Here's the example region I'm looking for from the original image:
https://www.dropbox.com/s/rvecsl390bfnu ... n.jpg?dl=0

And of course, the image itself can have lots of different connect components that aren't always on the right, etc.

Thanks!

Re: Find unused/blank area in an image

Posted: 2016-04-25T18:05:16-07:00
by snibgo
Well, that was Fred interpreting what I said.

This is how I would do it. Windows BAT syntax.

Code: Select all

%IM%convert drawing.jpg -fill Black +opaque White x.png

call %PICTBAT%innerTrim x.png

echo INNER_TRIM=%INNER_TRIM%
The result is:

Code: Select all

INNER_TRIM=352x89+0+0
This tells us a blank area is 352x89 pixels, starting at offset +0+0. You can use anywhere you like within that for your caption.

Re: Find unused/blank area in an image

Posted: 2016-04-25T18:53:46-07:00
by fmw42
What I was suggesting is simply threshold your image so that the "background" color that you want becomes white and everything else becomes black. Then use -connected-components to find the largest white area's bounding box.

Basically:

Code: Select all

convert image -fill black +opaque "yourbackgroundcolor" -fill white +opaque black resultimage
Now do connected components on resultimage and get the bounding box of the largest white region.

Sorry for the confusion about "background"

The problem is that your image has white completely on 3 sides. Thus your background color is white and connected components will se that as the full image. Even if you trim that top off, there are still regions of white such that connected components will see the largest white region as the full image.

So for such images, I do not think connected components is going to help much.

For this image, you could average the image down to one row and search along the row for contiguous regions of white and get the largest of such regions. However, this may not work for other images, i.e. it is not a universal solution.

Alternately, you can trim to get the flower pattern region, convert to black all the way vertically, then composite it at the same locations in a white background. Then use that for connected components

Code: Select all

dim=`convert drawing.jpg -format "%wx%h" info:`
ww=`echo "$dim" | cut -dx -f1`
hh=`echo "$dim" | cut -dx -f2`
trimvals=`convert drawing.jpg -fuzz 10% -format "%@" info:`
ww2=`echo "$trimvals" | cut -dx -f1`
offx=`echo "$trimvals" | cut -dx -f2 | cut -d+ -f2`
convert \( -size $size xc:white \) \
\( -size ${ww2}x${hh} xc:black \) \
-geometry +${offx}+0 -compose over -composite result.gif
But your best bet is to probably to use snibgo's innertrim, or IM compare to find some fixed size white region.

Re: Find unused/blank area in an image

Posted: 2016-04-25T20:21:05-07:00
by snibgo
Many methods are possible. innerTrim.bat needs a seed point, which defaults to the centre of the image. That works for this image, but might need adjusting for other images.

"-connected-components" can be used to find the colour of the largest component. The bounding box then isn't important; you could do a subimage-search for a rectangle of the found colour.

Or you could use the bounding box of the largest connected component: calculate the centre of the box, and use that s the seed point of innerTrim.bat.

I repeat a caution from my first post: don't use JPEG inputs unless you really have to.

Re: Find unused/blank area in an image

Posted: 2016-04-25T21:47:19-07:00
by fmw42
Snibgo,

You might look into using -morphology distance to get the seed point. I believe that the brightest point in the distance image from a binary mask would be furthest from all other regions and identify the "middle" of the largest white region. That point may not be a true centroid, but is a reasonable starting point.

Re: Find unused/blank area in an image

Posted: 2016-04-25T22:30:29-07:00
by snibgo
Yes, my "Inner Trim" page shows the "-morphology Distance" method. The result is guaranteed to be within the area. The centroid is not guaranteed to be within the area (for example, an area shaped like a "U").