A few general notes:
I expect a certain halo around the figure. However, I really don't want a scatter of not-quite-white pixels all over the background. It's okay if a few pixels inside of the figure get clipped to pure white, just so long as I don't do too much damage to it.
In response to specific suggestions:
I may be doing the wrong thing, but I -auto-level doesn't appear to do what I want. Doing "convert input.jpg -auto-level out.jpg", the resulting background isn't absolutely white. I wouldn't expect it to be, if I'm understanding -auto-level correctly, because it will only move the brightest pixel(s) value to white, so most of the slightly darker background would be lightened, but not turned absolutely white.
I had tried -contrast-stretch, and it seems tricky to calibrate for bulk images. For the given image, I had to go with "convert input.jpg -contrast-stretch 0x79% cs.jpg" to clear the background entirely (minus a bit of a halo around the figure itself, but I expect that). For others of my input images, 79% is clearly too large (eating aggressively into the figure) or too small (leaving a speckle of non-white pixels in the background). I couldn't figure out a way to automatically calculate it.
For anyone wanting snibgo's code in Bourne shell:
Code: Select all
#! /bin/sh
eval `convert input.jpg -gravity NorthWest -crop 160x160+0+0 -format "FR=%[fx:1.2*minima.r]\nFG=%[fx:1.2*minima.g]\nFB=%[fx:1.2*minima.b]\n" info:`
convert input.jpg -channel R -evaluate Divide $FR \
-channel G -evaluate Divide $FG \
-channel B -evaluate Divide $FB \
+channel \
out.png
(That's a fairly direct and clumsy translation.)
Taking snibgo's solution, applying it to my use of -level, and adjusting to be a bit more idiomatic, I ended up with this:
Code: Select all
#! /bin/sh
DARKLEVEL=`convert input.jpg -crop 160x160+0+0 -format "%[fx:100*min(minima.r,minima.g,minima.b)]" info:`
convert input.jpg -level 0,$DARKLEVEL% out.jpg
This works just off the single darkest value from any channel, and adjusts that point to absolute white. It also eliminates a pointless int() in my original. This also uses the upper left corner, not upper right. I meant upper left, but somehow typed upper right in my original post. My apologies.
I think that is better than my first attempt; it's more direct and easier to understand. There are a few things in there, but perhaps the most important piece is that I am now aware of minima, which I had previously overlooked.
This has been very educational, thank you! I'll definitely keep -evaluate Divide in mind. And this discussion helped me realize that perhaps I don't want one set of output images, but two: one set with a grey background for display, and a different set with a pure white background for later, manual manipulation. I'm also reconsidering if I want to do a single adjustment, or a per-channel adjustment.
Thank you!