0

I have >1k photos with "bad white" background and a photographic scale. I need a proper white background to put them for publication. However, I would like to avoid to crop them all in Photoshop by hand.

Issue = cropping the object as close as possible (= not just a bbox around the object) while keeping the photographic scale. I don't care about the shadow, it can be cropped or it can stay

I tried 1°PIL and a threshold: it keeps the scale but deletes all the white within the object; 2° rembg: it keeps white within the object but always crops the scale.

I have basic knowledge in Python but I'm not against to use something else if you have a better idea.

Many thanks for any tip,

Photo example. Red line is just for privacy reasons (=ID number)

lekythos
  • 113
  • 1
  • 8
  • might be worth adding a white-balance correction step to your workflow. would likely help any subsequent processing. if you've got the raw files from the camera (i.e. not JPEG) even better! the image contrast doesn't look very good either, some processing step for that might help as well. – Sam Mason Jul 05 '23 at 15:27

1 Answers1

0

You can do that with ImageMagick - available on macOS, Linux and Windows.

Try one with:

magick INPUT.JPG -fuzz 20% -trim RESULT.JPG

enter image description here

If you like that, do them all and write the modified files in a directory called TRIMMED with:

mkdir TRIMMED
magick mogrify -path TRIMMED -fuzz 20% -trim *.jpg

The -fuzz 20% means it will treat pixels that aren't quite white as white, so all pixels over 204 (out of 255) are considered white. This allows for JPEG inaccuracies and slightly non full-contrast images.


If you have an old, v6 ImageMagick like Debian or Ubuntu, the commands become:

convert INPUT.JPG -fuzz 20% -trim OUTPUT.JPG
mogrify -path TRIMMED -fuzz 20% -trim *.jpg

If you want to get the width, height and x,y offset of the trimbox and then trim more or less tightly, you can do that with:

magick RIMvd.jpg -fuzz 20% -format %@ info:
3688x2753+734+151

If you want to do it with PIL, open the image, invert and convert to a Numpy array, then sum the pixels across the rows and look for the first and last significantly non-zero row for the place to crop. Then sum the columns and do the same again. Something like:

from PIL import Image
import numpy as np

# Open image and make greyscale
im = Image.open(...).convert('L')
# Make Numpy array and invert
na = ~np.array(im)

rowSums = np.sum(na, axis=1)
colSums = np.sum(na, axis=0)
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432