Page 1 of 1

auto-crop

Posted: 2013-06-20T10:38:50-07:00
by steve___
I'm building a lightbox. Currently the raw images look similar to this:
http://i7.minus.com/jbishR4z6Gj9on.jpg

I'm looking to find away to auto crop the photos. Using this command:

Code: Select all

convert foo.jpg -fuzz 28% -trim +repage foo_crop.jpg
I get this result:
http://i2.minus.com/jzKZ3hGluvWPL.jpg

Is this the right way to go about it? If so, I assume the -fuzz 28% is
because my white balance is a bit blue? Also how would one have it not
crop so tight? I'd need a margin of 15px around the item.

-steve

Re: auto-crop

Posted: 2013-06-20T11:06:19-07:00
by fmw42
You can even out the background by averaging the top part of the image (above your object) to one row (-scale 1x1!), then expand it back to the size of the image (-scale WxH!) and subtract or divide it from the image. The you may get more reliable trim or smaller fuzz values.

To avoid cropping too close, you should apply your command without the +repage. Then get the trimmed size and offset (see string formats %O and %P or %@ below or identify -verbose) and then modify those values and simply crop the image.

I am sorry I do have to go out and cannot show you all the commands right now. But one of the others may be able to help before I get back.

But see
http://www.imagemagick.org/Usage/compose/#divide
http://www.imagemagick.org/script/escape.php
http://www.imagemagick.org/Usage/crop/#crop

Re: auto-crop

Posted: 2013-06-20T11:12:32-07:00
by snibgo
If your border was exactly white, you wouldn't need fuzz.

You can use "-border" to add a border.

Or you can not trim so much by using "-verbose" (without "+repage"), then doing an adjusted crop.

Code: Select all

D:\web\im>%IM%convert -fuzz 28% jbishR4z6Gj9on.jpg -verbose -trim j.jpg
jbishR4z6Gj9on.jpg=>j.jpg JPEG 900x600=>151x44 900x600+398+283 8-bit sRGB 5.09KB 0.000u 0:00.004
This gives the same crop:

Code: Select all

D:\web\im>%IM%convert jbishR4z6Gj9on.jpg -crop 151x44+398+283 j.jpg
This gives a reduced crop:

Code: Select all

D:\web\im>%IM%convert jbishR4z6Gj9on.jpg -crop 181x74+383+268 j.jpg

Re: auto-crop

Posted: 2013-06-20T11:40:36-07:00
by GreenKoopa
You can automate snibgo's suggestion of using -verbose to get the crop information. This gives you a string to pass to the next command.

Code: Select all

convert foo.jpg -fuzz 28% -trim -print "%[fx:w+30]x%[fx:h+30]+%[fx:page.x-15]+%[fx:page.y-15]" null:
How to capture and use this string is platform specific. If you must have this in one command, anthony recently added support to -distort for percent escapes. This can be used to crop, but the command is somewhat long.

More important that your white balance is the uneven lighting and vignetting. There are several techniques to correct this, and fmw42's is a great one. The best method depends on the range of photos you have.

Re: auto-crop

Posted: 2013-06-20T17:51:15-07:00
by fmw42
If you want to remove the bluish tint, trim and pad (by say 5 all around), you can do one of the following two methods:

Note Unix syntax

1)

dim=`convert jbishR4z6Gj9on.jpg \
\( jbishR4z6Gj9on.jpg[900x250+0+0] jbishR4z6Gj9on.jpg[900x250+0+250] -scale 1x1! -evaluate-sequence mean -scale 900x600! \) \
+swap -compose divide -composite +write 1tmp1.png -fuzz 28% -trim -format "%w,%h,%X,%Y" info:`

W=`echo $dim | cut -d, -f1`
H=`echo $dim | cut -d, -f2`
X=`echo $dim | cut -d, -f3 | tr -d "+"`
Y=`echo $dim | cut -d, -f4 | tr -d "+"`

W=$((W+10))
H=$((H+10))
X=$((X-5))
Y=$((Y-5))

newdim="${W}x${H}+${X}+${Y}"

convert 1tmp1.png -crop $newdim +repage 1tmp1_crop.jpg


or simply

2)

convert jbishR4z6Gj9on.jpg \
\( jbishR4z6Gj9on.jpg[900x250+0+0] jbishR4z6Gj9on.jpg[900x250+0+250] -scale 1x1! -evaluate-sequence mean -scale 900x600! \) \
+swap -compose divide -composite -fuzz 28% -trim +repage -bordercolor white -border 5 1tmp1_trim_border.jpg

Re: auto-crop

Posted: 2013-06-21T08:39:42-07:00
by steve___
Wow thanks a lot, it really is appreciated.

-steve

Re: auto-crop

Posted: 2013-06-21T08:58:22-07:00
by steve___
Is there a nice way to get around using -fuzz? I'm concerned the
the percentage I settle on will either be too greedy or too loose.

-steve

Re: auto-crop

Posted: 2013-06-21T09:59:46-07:00
by fmw42
steve___ wrote:Is there a nice way to get around using -fuzz? I'm concerned the
the percentage I settle on will either be too greedy or too loose.

-steve
Not that I know in IM.

Re: auto-crop

Posted: 2013-06-21T11:25:43-07:00
by GreenKoopa
steve___ wrote: Is there a nice way to get around using -fuzz? I'm concerned the percentage I settle on will either be too greedy or too loose.
A good concern. Adding a white border will help give you a more consistent result. The -fuzz number will be larger, but the distance will be from white so will be smaller in effect .

Code: Select all

convert foo.jpg -bordercolor white -border 1 -fuzz 35% -trim +repage foo_crop.jpg
-fuzz is the easy but dumb answer. Cleaning up the photo is much more difficult, but will allow you to use a smaller -fuzz. fmw42 offered some good ideas on cleaning up the photo's background. Or you could try -trim in a different colorspace, especially if your objects have some color and your background has none. Better lighting may be the easy first step.

Re: auto-crop

Posted: 2013-06-21T13:09:08-07:00
by snibgo
Using Gimp, I see the blueness seems to apply almost equally across the entire image, including the object. A typical RGB value is (223, 218, 248). So my first step would be to remove this.

Code: Select all

%IM%convert ^
  jbishR4z6Gj9on.jpg ^
  -channel R -evaluate Multiply 0.9776 ^
  -channel B -evaluate Multiply 0.8790 ^
  j.png
The uneven tone seems to apply to the background only, not the object.

We might then use edge detection to find the limits of object. The fuzz value is not critical. Beware: Windows sorcery follows.

Code: Select all

for /F %%f ^
in ('%IM%convert j.png ^
  -edge 1 ^
  -bordercolor Black -border 1 ^
  -fuzz 50%% ^
  -draw "color 0,0 floodfill" ^
  -shave 1x1 ^
  -trim ^
  -format "NEWCROP=%%wx%%h%%X%%Y\n" ^
  info:') ^
do set %%f
And use this to crop the colour-corrected image:

Code: Select all

%IM%convert ^
  j.png ^
  -crop %NEWCROP% ^
  jCropped.png

Re: auto-crop

Posted: 2013-06-23T18:13:52-07:00
by anthony
What you are basically doing is trying to seperate the object from the background, then find its location.

The -trim is a very raw, low level technique. With a border of white, you are essentually doing a raw threshold at a fixed greylevel. That is some thing equivelent to...

convert input.png -threshold 35% mask.png

The mask is just a black and white pattern that should define what is foreground and background. The trim then just finds its bounds.

Separating a foreground object from the background can be hard, especially with the large gradients you are seeing, though as you are not after the exact shape, this task is not as hard as full background removal.

I remember Fred created a LOT of different scripts to try and do this type of separation in very horrible conditions.
See Fred's ImageMgaick Scripts http://www.fmwconcepts.com/imagemagick/
and go down the page to 'Threshold Segment' scripts. Most of these are 'histogram separation' techniques,
but it should let you remove (well automate) the 'fuzz' factor in a number of different ways.
Especially see the 'comparison page'.
http://www.fmwconcepts.com/imagemagick/ ... /index.php

Doing a small amount of morphology could also help smooth out the mask before finding its bounds.