Page 1 of 1

contrast-stretch without blackpoint

Posted: 2011-10-21T06:47:00-07:00
by obir
Hi all,
I'm trying to implement a contrast-stretch that stretches the whitepoint of an image to 100% but leaves the blackpoint alone.
For instance if the darkest point in an image is 30% white and the lightest point is 85% white, i want it to stretch from 30% to 100% (but not from 0% to 100%).

So far i've tried:
convert myimage -contrast-stretch 0x0.04% myimagenew
.. but even though the first number is zero (specified as: the percentage of pixels that should be in the darkest "basket" ) this still stretches the images from 0% to 100%.

I've also tried the 'autowhite' script from fred's IM-scripts: http://www.fmwconcepts.com/imagemagick/ ... /index.php
Unfortunately this script uses a lot of resources (up to 30 times more than a simple contraststretch) and on some images throws a divison-by-zero error.

Any hints or suggestions? -- Would be greatly appreciated!
Regards, Obir

Re: contrast-stretch without blackpoint

Posted: 2011-10-21T09:36:46-07:00
by fmw42
Get the maximum value in the image, convert to percent. Then use -level 0,max% leaving the max at your measured value and the min at 0.

in unix, this would be
maxpct=`convert image -format "%[fx:100*maxima]" info:`

convert image -level 0,maxpct% result


see http://www.imagemagick.org/script/fx.php and http://www.imagemagick.org/Usage/color_mods/#levels

Re: contrast-stretch without blackpoint

Posted: 2011-10-21T12:44:45-07:00
by obir
Thanks, i've tried it, it works very well, exactly what i needed..!
Although I'm still trying to understand why it works.. :)
Intuitively i would have expected: get the minimum value in the image, and then use: convert image -level minimum,100% result
Trying to wrap my head around this..
Thanks again.. a lot!
Regards,
Obir

Re: contrast-stretch without blackpoint

Posted: 2011-10-21T13:33:35-07:00
by fmw42
obir wrote:Thanks, i've tried it, it works very well, exactly what i needed..!
Although I'm still trying to understand why it works.. :)
Intuitively i would have expected: get the minimum value in the image, and then use: convert image -level minimum,100% result
Trying to wrap my head around this..
Thanks again.. a lot!
Regards,
Obir

-level min,max% stretches the min to 0 (black) and the max to 1 (white). So if you set the min to 0 and the max to your max value, it won't change the min as it is already set to 0 (black), but will stretch the max to white.

Re: contrast-stretch without blackpoint

Posted: 2011-10-21T22:20:59-07:00
by anthony
Try -linear-stretch the arguments are the number of pixels that should be clipped at black or white respectively. A argument of zero makes no change.

As such... -linear-stretch 0,1 will do what you want.

NOTE: -normalize, -contrast-stretch, and -linear-stretch all generate a histogram (using 1024 bins) to determine the color position to stretch. as such it is not 'exact'. The other difference is how 'zero' is handled, and that -linear-stretch actually does a -level operation to do the stretch, while -contrast-stretch uses histogram bin values for color replacement stretching (which introduces a 1024 quantum rounding effect. -normalize uses -contrast-stretch internally.

This is an area I have always felt should be re-developed in ImageMagick, probably using some 'compound' operator. I even made a start, with a special "histogram.c" module in which I implemented a mathematically perfect normalization stretching operator -auto-level, and a greyscale centring operator -auto-gamma. Unfortunately a white or black, only version while possible easily implemented in the Core API, has not been. :(

Re: contrast-stretch without blackpoint

Posted: 2011-10-22T01:56:10-07:00
by obir
The other difference is how 'zero' is handled
I just compared -contrast-stretch 0,1 and -linear-stretch 0,1 and you're right, -linear-stretch 0,1 makes no change to the blackpoint where -contrast-stretch 0,1 does.
I must have overlooked this when searching through the list of operators.
Thanks for your suggestion, and fmw42, thanks for your explanation of the level operator.
Regards,
Obir