7

I'm trying to use ImageMagick(7.1.1-43) to automatically crop a photograph of a coin, removing the surrounding background. I want to trim the image based on a "fuzz" factor, effectively removing the mostly-uniform color. However, my current command only trims the left side of the image, leaving the right side untouched.

My Goal:

I want to trim both the left and right sides of the image equally, removing as much of the wall as possible while preserving the coin.

Command Used:

./magick 20240614_093525.JPG -fuzz 51% -trim +repage img1.jpg

Original Image:

enter image description here

Returned Image:

enter image description here

What I've Tried:

I've tried adjusting the -fuzz percentage, but it doesn't seem to affect the left side trimming. Lowering it too much prevents any trimming, and raising it produces this error:

magick: geometry does not contain image `20240614_093525.JPG' @ warning/attribute.c/GetImageBoundingBox/554.

What command can I use to ensure both sides are trimmed?

Destroy666
  • 12,350

3 Answers3

10

The image isn't great for fuzzy matching because of the vignette that's much darker in upper right corner. The imbalance of the intensity of the coin's shadow doesn't help either. Setting fuzziness too high results in nothing because the coin isn't too far off coloristically from the background.

You can also play around with -define trim:percent-background parameter which affects trim's internal background similarity percentage rather than overall color similarity. E.g. this:

magick in.webp -fuzz 48% -define trim:percent-background=99.5% -trim +repage out.webp

resulted in the best accuracy from my quick tests going down from 50% fuzziness and default 100%:

Almost correct coin

But even much better results happen if you process the vignette first. E.g. just using -shave 50x50 to cut out corners and then processing the resulting image yields much better results with lower global fuzziness, like:

magick out.webp -fuzz 45% -define trim:percent-background=98.5% -trim +repage out.webp

Even more accurate coin

For it to be more automated with let's say way more intensive vignette or varying objects that are foreground, in let's say batch processing, either much more advanced algorithms or even AI would need to be used.

Destroy666
  • 12,350
9

The issue you have is that you have a gradated (shadows?) background. So fuzz alone would need a high value. It would help if you crop the image first with -shave. Then the fuzz might not need such a high value.

On the other hand, you can help -trim in Imagemagick 7 with one of the -trim defines that forces the trim to trim until it reaches some (-background) color. See https://imagemagick.org/script/command-line-options.php#trim or https://imagemagick.org/script/defines.php

magick image.webp -background "gray(200)" -define trim:percent-background=100% -fuzz 49% -trim +repage img1.jpg

enter image description here

fmw42
  • 201
  • 2
  • 6
2

You could leverage the fact that the unwanted background is plain and untextured, and therefore has low variance...

First, convert the image to greyscale, then measure the variance at each pixel location by looking at the surrounding 9x9 pixels. Threshold at a low value and get the trimbox. Apply that to original, coloured image.

trimbox=$( magick coin.webp -colorspace gray -statistic standarddeviation 9x9 -threshold 10% -format %@ info: )
magick coin.webp -crop $trimbox result.png

enter image description here


How it works...

This command thresholds the variance:

magick coin.webp -colorspace gray -statistic standarddeviation 9x9 -threshold 10% variance.jpg

and results in this:

enter image description here

This command calculates the trimbox:

magick coin.webp -colorspace gray -statistic standarddeviation 9x9 -threshold 10% -format %@ info:

and results in this:

1718x1746+661+42