apply normalization to a masked image but stretch all

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
omilu
Posts: 4
Joined: 2012-09-23T09:09:14-07:00
Authentication code: 67789

apply normalization to a masked image but stretch all

Post by omilu »

Is there a way to apply -normalization or -contrast-stretch to a masked image, so that the black point/white point computation ignores the masked part of the image, and the resulting black point white point stretch is applied to the whole image

When i try

convert fire.png -clip-mask maskfire.png -normalize out.png

I get the same white point black point as
convert fire.png -normalize out.png

How can i have the stretch computation, ignore the masked part?
Last edited by omilu on 2012-09-24T20:30:39-07:00, edited 1 time in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: apply normalization to a masked image but stretch all

Post by fmw42 »

try adding -channel rgba -alpha on after reading the input
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: apply normalization to a masked image but stretch all

Post by anthony »

Invert the mask before using.

The mask is a write mask, as in the mask when 'off' or 'black' stops some parts being writable, as in the pixel data is not updated. That however does not prevent most operator from calculating the unwraitable pixel data. IMv7 has facilities to allo such operators from avoiding calculation of unwriate pixels.

See IM examples, Masking, Write Masks...
http://www.imagemagick.org/Usage/masking/#write_mask
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
omilu
Posts: 4
Joined: 2012-09-23T09:09:14-07:00
Authentication code: 67789

Re: apply normalization to a masked image but stretch all

Post by omilu »

Thanks guys.

I don't understand you're suggestions, can you give an example. If I invert the mask, won't it end up just masking the opposite part of the image.

I am trying to contrast stretch an image that has a few areas that are much higher signal values, if I normalize the entire image, than the high values throw off the stretch. If I mask the high signal values, and perform normalization on everything else, the resulting contrast stretch is perfect, but the masked areas are not affected by the stretch.

I need some way for the normalization step to compute the white point / black point with the high signal areas masked (not part of the computation), but than apply the computed stretch on the whole image, (with the high signal value areas stretched just like the rest of the image.

If I try

convert fire.png -clip-mask firemask.png -negate out.png

this just inverts the mask which ends up masking the wrong part of the image.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: apply normalization to a masked image but stretch all

Post by fmw42 »

Post a link to your input image and mask image, so we can see what is going on and test with them.

PS, If you mask image is grayscale and not binary, then you should be using -mask

http://www.imagemagick.org/script/comma ... s.php#mask
omilu
Posts: 4
Joined: 2012-09-23T09:09:14-07:00
Authentication code: 67789

Re: apply normalization to a masked image but stretch all

Post by omilu »

I apologize, I misstated the behavior of image magick in my original question but the intent of the question still stands.
Here is what I observe with links to sample image.

When I mask the high signal areas and perform normalization
-convert orig.png -clip-mask firemask.png -normalize withmask.png

image magick computes the same black point/white point as when I do the same step without the mask
-convert orig.png -normalize withoutmask.png

The mask only prevents the contrast stretch from being applied to the masked area. It does not affect the computed black point white point, in other words the computed black point white point is the same whether I use a mask or not.

What I need is for image magick to ignore the masked area when computing the black point/white point. Is there a way to get image magick to ignore the high signal areas when computing the black point / white point, but then apply the resulting contrast stretch black point white point to the whole image (ignoring the mask)


the original image -contrast-stretch 0
https://www.dropbox.com/s/lz4tswac4rntyhk/orig.png
the binary mask (created by thresholded the original to some level)
https://www.dropbox.com/s/ukas4e5in40qek6/firemask.png
the result of (using the mask) -convert orig.png -clip-mask firemask.png -contrast-stretch 1%x2%
https://www.dropbox.com/s/i9q70k345es2wjn/withmask.png
the result of (not using the mask -convert orig.png -contrast-stretch 1%x2%
https://www.dropbox.com/s/s864ds32707ika0/nomask.png
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: apply normalization to a masked image but stretch all

Post by fmw42 »

My understanding is that you need a read mask, which is not available in IM 6, but will be available in IM 7. I had the need to do something similar and that was what I was told. If it was the mean and not the min, max, then you could use the technique I provided earlier with my link to my tidbits page.

Assuming that the min of your region is not zero, you can create a binary mask, multiply it by the image, then feed the result to txt: and pipe the results to grep to find everything that is not zero, then pipe to sort and then get the first and last entries.

Assume the following has been created by a an elliptically shaped mask by multiplying the mask by some image (such as a gradient here):

Image


str=`convert shape_ellipse.gif txt: | tail -n +2 | tr -cs "0-9\n" " " | cut -d\ -f 3 | grep -v "0" | sort`
min=`echo "$str" | head -n 1`
max=`echo "$str" | tail -n 1`
echo "min=$min; max=$max"

min=1; max=98
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: apply normalization to a masked image but stretch all

Post by anthony »

OKAY I have seen this before.

The short answer is no. Normalization does not ignore colors that are transparent (or masked), and as such
the 'hidden' color effects the result. If the hidden color is black, the black level will not change, as the operator thinks those pixels already at the black limit.

This I consider a BUG.

What SHOULD happen is that when the channel 'sync' flag is enabled (channel setting has not been modified) IM should not only normalize all color channels equally, but it should ignore any pixel that is fully transparent pixels. this should happen for all normalization operators, -normalize, -contrast-stretch, -level-stretch, and -auto-level.


The LONG answer and solution, is to use the mask to set the masked pixels to a 'mid-tone' color that will
not effect results. That is some color that already exists in the image. Any such color will then not be a 'limiting color value' and as such will not effect normalization. Save the original image if you need to preserve these 'masked' pixels.

Also note that -normalize is not a perfect normalization but one designed for general images (read JPEG). You should use -auto-level
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
omilu
Posts: 4
Joined: 2012-09-23T09:09:14-07:00
Authentication code: 67789

Re: apply normalization to a masked image but stretch all

Post by omilu »

fred, thanks for the script sample, i had one that did somthing similar but was twice as long and convoluted.

Anthony, thankyou for the tip, it works!. I can mask the high signal areas and use -contrast-stretch, -autolevel etc... and imagemagick now computes the new black point/white point as if the masked area wasn't there.

But now for the 2nd part, any idea how I can apply this black point / white point stretch to the whole image as if the mask wasn't there?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: apply normalization to a masked image but stretch all

Post by anthony »

You would keep a copy of the original image, and use the mask to merge (compose) the areas that were masked (so as not to effect normalization, into the final results. That is copy the pixels that you had modified back to there original state.

I myself have not needed to do that as I simply did not want those pixels.

In IMv7 the normalization operators could be changed so it ignores any pixel that is either alpha masked, or given a secondary 'read' mask. BUt that will probably be in BETA testing.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply