-contrast-stretch problem?

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
Post Reply
agss

-contrast-stretch problem?

Post by agss »

-contrast-stretch doesn't appear to behave as documented when a
non-percent white-point is specified. The documentation says:
Increase the contrast in an image by stretching the range of
intensity values. While doing so black-out at most black-point
pixels and white-out at most white-point pixels. Or, if percent is
used, black-out at most black-point % pixels and white-out at most
100% minus white-point% pixels.
However, -contrast-stretch 0x0 whites-out all pixels in the image I
tried to convert, not 0 as the doc leads me to expect. This is 6.4.4-3
under Mac OS X 10.4.11.

Assuming the documentation is correct, the patch below looks to do the
job.

Anders

Code: Select all

*** wand/mogrify.c.orig	Fri Oct  3 21:34:27 2008
--- wand/mogrify.c	Sat Oct 11 00:06:51 2008
***************
*** 914,919 ****
--- 914,922 ----
              if ((flags & SigmaValue) == 0)
                white_point=(MagickRealType) (*image)->columns*(*image)->rows-
                  black_point;
+             else if ((flags & PercentValue) == 0)
+               white_point=(MagickRealType) (*image)->columns*(*image)->rows-
+                 geometry_info.sigma;
              (void) ContrastStretchImageChannel(*image,channel,black_point,
                white_point);
              InheritException(exception,&(*image)->exception);
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: -contrast-stretch problem?

Post by fmw42 »

However, -contrast-stretch 0x0 whites-out all pixels in the image I
tried to convert, not 0 as the doc leads me to expect. This is 6.4.4-3
under Mac OS X 10.4.11.
I believe you want -constrast-stretch 0 or -contrast-stretch 0x100% (or -contrast-stretch 0,100%)

This will find the min and max values and stretch them to full black and full white.

Note that 0x0 will take the min and stretch to black and the min again and stretch to white, so you will get all white

To clip a few percent from the white end, use 100-few percent.

-normalize is the same as -contrast-stretch 2x99% as it clips 2% from the low and 1% from the high
agss

Re: -contrast-stretch problem?

Post by agss »

Note that 0x0 will take the min and stretch to black and the min again and stretch to white, so you will get all white
Indeed, but my point was that this isn't what the documentation says it should do. It says that 0x0 will black-out at most 0 pixels, which it does, and white-out at most 0 pixels, which it doesn't.

Admittedly, 0x0 isn't the most interesting example and isn't what I tried at first. Instead, I tried something like 0x1000 expecting at most 1000 pixels to be whited-out but saw that this wasn't the case. Either the documentation is wrong is saying that white-point is the maximum number of pixels that will be whited-out (which seems to me the more useful semantics) or convert isn't behaving as documented.

Anders
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: -contrast-stretch problem?

Post by fmw42 »

agss wrote:
Note that 0x0 will take the min and stretch to black and the min again and stretch to white, so you will get all white
Indeed, but my point was that this isn't what the documentation says it should do. It says that 0x0 will black-out at most 0 pixels, which it does, and white-out at most 0 pixels, which it doesn't.

Admittedly, 0x0 isn't the most interesting example and isn't what I tried at first. Instead, I tried something like 0x1000 expecting at most 1000 pixels to be whited-out but saw that this wasn't the case. Either the documentation is wrong is saying that white-point is the maximum number of pixels that will be whited-out (which seems to me the more useful semantics) or convert isn't behaving as documented.

Anders
You are right about the non-percent statement. It may be working on gray levels and not counts as its parameters are black-point and white-point. But I could be wrong. So I suspect it may work as graylevel from black (at the low end) and quantumrange-graylevel (at the high end). However, if count is correct, then it would be count from min graylevel (at the low end) and totalpixels-count from the max graylevel (at the high end). That would be more consistent with the percent statement,

" Or, if percent is used, black-out at most black-point % pixels and white-out at most 100% minus white-point% pixels."

I have always used percent and found that convenient except for -contrast-stretch 0 which then clips at the true (histogram) min and max.

However, clarification is indeed in order.
agss

Re: -contrast-stretch problem?

Post by agss »

I've constructed an example to try and figure out what the argument to -contrast-stretch actually is: an artificial image with three shades of gray in 100x100 pixel squares.

Code: Select all

convert -size 100x100 'xc:rgb(192,192,192)' \
        -bordercolor 'rgb(128,128,128)' -border 100 \
        -bordercolor 'rgb(64,64,64)' -border 100 \
        -crop 300x100+0+200 \
        test.ppm
(Possibly there's a better way to construct this?) Do -contrast-stretch 0:

Code: Select all

convert test.ppm -contrast-stretch 0 x:
The darkest gray has now gone black and the lightest one white. That's what I expected. Now, say I replace 0 by an integer black-point in percent form. For 0% through 33% the result is the same: the darkest gray goes black, the lightest goes white, the middle gray is unchanged. From 67% through 99% the two darkest grays both go black and the lightest goes white. At 100% the entire image goes black. This speaks for the black-point actually being a pixel count since one third of my image is in each shade of gray. However, I can't say I understand why the result for 34% through 66% is that the image is completely unchanged: nothing goes black or white. I would have expected the same result as for either 33% or 67%, depending on how aggressive -contrast-stretch is. (That said, doing nothing in every case arguably satisfies the documented requirements on its behaviour. :^)

I get the same results if I use a non-percent form given the fact that my image has 10000 pixels in each shade of gray: with a contrast stretch of 9999 I get black gray white; 10000 and 19999 give an unchanged image; 20000 and 29999 give black black white; 30000 gives all black.

So black-point and white-point do seem to represent pixel counts as documented but I'm still a little confused by the behaviour I see and my initial observation that a non-percentage white-point doesn't behave in the documented manner still seems to hold.

Hopefully someone can clarify matters.

Anders
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: -contrast-stretch problem?

Post by fmw42 »

agss wrote:I've constructed an example to try and figure out what the argument to -contrast-stretch actually is: an artificial image with three shades of gray in 100x100 pixel squares.

Code: Select all

convert -size 100x100 'xc:rgb(192,192,192)' \
        -bordercolor 'rgb(128,128,128)' -border 100 \
        -bordercolor 'rgb(64,64,64)' -border 100 \
        -crop 300x100+0+200 \
        test.ppm
(Possibly there's a better way to construct this?) Do -contrast-stretch 0:

Code: Select all

convert test.ppm -contrast-stretch 0 x:
The darkest gray has now gone black and the lightest one white. That's what I expected. Now, say I replace 0 by an integer black-point in percent form. For 0% through 33% the result is the same: the darkest gray goes black, the lightest goes white, the middle gray is unchanged. From 67% through 99% the two darkest grays both go black and the lightest goes white. At 100% the entire image goes black. This speaks for the black-point actually being a pixel count since one third of my image is in each shade of gray. However, I can't say I understand why the result for 34% through 66% is that the image is completely unchanged: nothing goes black or white. I would have expected the same result as for either 33% or 67%, depending on how aggressive -contrast-stretch is. (That said, doing nothing in every case arguably satisfies the documented requirements on its behaviour. :^)

I get the same results if I use a non-percent form given the fact that my image has 10000 pixels in each shade of gray: with a contrast stretch of 9999 I get black gray white; 10000 and 19999 give an unchanged image; 20000 and 29999 give black black white; 30000 gives all black.

So black-point and white-point do seem to represent pixel counts as documented but I'm still a little confused by the behaviour I see and my initial observation that a non-percentage white-point doesn't behave in the documented manner still seems to hold.

Hopefully someone can clarify matters.

Anders

I did some test and it appears that -contrast-stretch does use counts or percent counts.

I made a 1x1000 pixel gradient:

convert -size 1000x1 gradient: -rotate 90 grad1000.png
identify -verbose grad1000.png
shows 1 pixel at each of 1000 graylevels between 0 (black) and 65535 (white)

Then I issued the following to clip by percent count of 10% on each end:

convert grad1000.png -contrast-stretch 10,90% grad1000_cs10x90pct.png
identify -verbose grad1000_cs10x90pct.png
...
Histogram:
101: ( 0, 0, 0) #000000000000 black
101: (65535,65535,65535) #FFFFFFFFFFFF white
Thus 10% or 100 pixels were clipped to black and white each in addition to the 1 already there, so a value of 101 counts on each end.

Then I issued the following to clip by count of 10 on each end:

convert grad1000.png -contrast-stretch 10,990 grad1000_cs10x990t.png
identify -verbose grad1000_cs10x990.png
...
Histogram:
11: ( 0, 0, 0) #000000000000 black
11: (65535,65535,65535) #FFFFFFFFFFFF white
Thus 10 pixels were clipped to black and white each in addition to the 1 already there, so a value of 11 counts on both ends.

Thus the correct use of -contrast-stretch is by count from 0 at the black/low end and (totalpixels - count) from white/high end for non-percent. And percentcount from the black/low end and (100-percentcount) from the white/high end.

Thus the documentation is confusing if not wrong.

black-point value = either number of pixels to black out or percent pixels to black out [at the low end of the histogram]".
white-point value = either (total pixels minus number of pixels to white out) or (100 - percent pixels to white out) [at the high end of the histogram]
petersteier
Posts: 2
Joined: 2016-07-23T00:59:42-07:00
Authentication code: 1151

Re: -contrast-stretch problem?

Post by petersteier »

In the present version, contrast-stretch does not work at all 10%x90% has no effect at all, 10%x80% whitens almost the wole page. This behaviour is different from previous versions. They messed it up.
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: -contrast-stretch problem?

Post by snibgo »

(a) Please don't double-post.

(b) There are many "present versions" of IM. Please say which one you are using, on what platform.

(c) Please be more specific about the problem, and provide commands that will show the problem. If required, also include your input and output images.

"-contrast-stretch" seems to work fine, for me, on IM 6.9.5-3.
snibgo's IM pages: im.snibgo.com
Post Reply