Find unused/blank area in an image

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
troydsmith
Posts: 3
Joined: 2016-04-24T14:20:10-07:00
Authentication code: 1151

Find unused/blank area in an image

Post 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!
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find unused/blank area in an image

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find unused/blank area in an image

Post 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
troydsmith
Posts: 3
Joined: 2016-04-24T14:20:10-07:00
Authentication code: 1151

Re: Find unused/blank area in an image

Post 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?
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find unused/blank area in an image

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find unused/blank area in an image

Post 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?
troydsmith
Posts: 3
Joined: 2016-04-24T14:20:10-07:00
Authentication code: 1151

Re: Find unused/blank area in an image

Post 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!
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find unused/blank area in an image

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find unused/blank area in an image

Post 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.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find unused/blank area in an image

Post 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.
snibgo's IM pages: im.snibgo.com
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Find unused/blank area in an image

Post 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.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: Find unused/blank area in an image

Post 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").
snibgo's IM pages: im.snibgo.com
Post Reply