Problem with normalizing channels in concert

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.
cra3y

Problem with normalizing channels in concert

Post by cra3y »

i try to normalize this picture by all channes in concert by command below:

Code: Select all

convert before.jpg -channel Gray -normalize -channel RGB -quality 90 after_n.jpg
before:
Image

after normalizing:
Image

i got similar results with contrast-stretch command below:

Code: Select all

 convert before.jpg -channel Gray -contrast-stretch 0%x99.5% -channel RGB -quality 90 after_c.jpg
after contrast-stretching:
Image

How Can I do normalize all channels non-separately (in concert)?

Command switch -normalize (alone) do normalize each channel separately, but this don't interest me.

PS: ImageMagick 6.2.9 09/12/06 Q16
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Post by magick »

You have discovered a bug. We will have a patch in ImageMagick 6.2.9-7 Beta by tommorrow. 6.2.9-7 is scheduled for release within a week or two. Thanks for the problem report. Note, with the patch you will need to use -channel all instead of -channel gray.
cra3y

Post by cra3y »

magick wrote: You have discovered a bug. We will have a patch in ImageMagick 6.2.9-7 Beta by tommorrow. 6.2.9-7 is scheduled for release within a week or two. Thanks for the problem report. Note, with the patch you will need to use -channel all instead of -channel gray.


ok. i will wait for beta, i will test tommorow and report if problem still persist.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

I beg to differ, it is not a bug but incorrect usage!!!!!

IM Examples just got caught out by the 'not a bug fix', and I had to report a bug to fix the 'fix'.

The original problem is that -channels Grey is equivelent to -channels Red.
This is an internal thin in IM and menas you are not using channels correctly.

The default is to normalize by the channels RGB, so not using any -channel setting
at alls will have produced a correct normalization of your image...
How Can I do normalize all channels non-separately (in concert)?

By only using "-chennels RGB", whcih is the default!

For details of what -normalize does do see IM Examples Color Manilulation
http://www.cit.gu.edu.au/~anthony/graph ... #normalize
However because of the bug one examples is current incorrect!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

anthony wrote:
How Can I do normalize all channels non-separately (in concert)?

By only using "-chennels RGB", whcih is the default!


wrong, -channel RGB -normalize cause normalize each channel separately, this change WhiteBalance of picture
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

It should not have. That was the point of the original change. However -channel grey
would definatally be the cause of the 'red' result!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

i downloaded and compiled latest beta today and i performed some tests

normalize by hand (levels)

Code: Select all

convert before.jpg -level 0%,39% -quality 90 normalize_by_levels.jpg
Image

normalize by -channel all and contrast-stretch

Code: Select all

convert before.jpg -channel all -contrast-stretch 0%x99.7% -channel RGB -quality 90 contrast_stretch_cs.jpg
Image

still something is wrong
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

Problem has not been fixed in beta release. Patience.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

anthony wrote: Problem has not been fixed in beta release. Patience.


when will You fix this problem? i tried latest IM (6.3.0-2) but still persist
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

From everything I have seen it is fixed. prehaps I am missing the problem.

What is exactly wrong with it now.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

anthony wrote: From everything I have seen it is fixed. prehaps I am missing the problem.

What is exactly wrong with it now.


ok, let download image named as "before.jpg" from this post

please "normalize" by hand - levels command like this

Code: Select all

convert before.jpg -level 0%,39% -quality 90 normalize_by_levels.jpg
Image

ok, levels command stretching histogram for each channel by the same multiplier, so White balanse is not changed

let normalize by "auto" like contrast-stretch

Code: Select all

convert before.jpg -channel all -contrast-stretch 0%x99.7% -channel RGB -quality 90 contrast_stretch_cs.jpg
Image

this command should also normalize but each channel by different multiplier, so white paper looks more greenish than picture normalized by leves

let see syntetic test
this is synth.jpg which contain gray gradient to about 128 in RGB values and solid pink to about 230 to R and B channels
Image

let normalize by hand - each channel by the same multiplier

Code: Select all

convert synth.jpg -level 0%,80% -quality 90 -quality 90 synth-levels.jpg
Image
ok, pink color reach near 255 in R and B, gray gradient reach about 161 in each channel and it still was gray

white balance is preserved

ok, let normalize byc contrast - stretch

Code: Select all

convert synth.jpg -channel all -contrast-stretch 0%x99.7% -quality 90 synth-contrast-stretch.jpg
Image
pink color is ok, but this command cause normalize green channel to max that cause greenish gradient, because it was absent in pink solid rectangle

white balance is not preserved

also, let try -normalize command

Code: Select all

cconvert synth.jpg -channel all -normalize -quality 90 synth-normalize.jpg
Image
results from this command was similar to contrast-stretch

white balance is not preserved

:-)
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

I downloaded the 'synth.jpg' image you generated (my current IM, v6.3.1-0, is broken with regard to gradient image generation).

Code: Select all

     convert synth.jpg -normalize  x:
worked fine, I get a grey area (black to white) and a pink area, no green.

however adding -channel all does produce 'green', as does -channel RGBA

I think what is happening is that the channel tie is only happening when channel is set to its default RGB value. That is the problem, and in some ways makes sense.
if 'A' channel is involved, it should not be tied to the RGB channels.

Two solutions, leave it and ensure channels are reset with +channel to tie them together.
OR. always tie RGB channels together, if all three channels are present in the -channel setting then do 'A' channel separateally.

To my thinking the former is more logical, with a update to the IM Example notes, plus a method of the channel ties in the online manual.

Is this acceptable?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

anthony wrote: Two solutions, leave it and ensure channels are reset with +channel to tie them together.
OR. always tie RGB channels together, if all three channels are present in the -channel setting then do 'A' channel separateally.

To my thinking the former is more logical, with a update to the IM Example notes, plus a method of the channel ties in the online manual.

Is this acceptable?


i tried Your way to normalize by adding +channel

Code: Select all

convert synth.jpg +channel -normalize -quality 90 synth-normalize.jpg
Image

this one preserve white balance, but not luminance proportion of picture, the pink solid was normalized from 230,0,230 to 255,1,255 but
gray gradient was normalized from 128,128,128 to 255,255,255 to max 255 RGB

i'm asked for normalizing like method described below:
open synth or before.jpg in gimp
choose Layer->Colors->Levels
move white slider to left, until reach "smallest" peak in histogram, move black slider to right until reach smallest peak in historgram
Image
this metod is called "histogram stretch" for overal picture, IMHO contrast-stretch should perform in this way.

could You add this behaviour/method as new command for example: histogram-stretch (without parameters, work as normalize) and histogram-stretch nxy (syntax like contrast-stretch)?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

Okay in sumary you desire is...

Where -contrast-stretch is expands from the point a percentage inward from the highest 'peak' colors, a -histogram-stretch would expand the points given by having a percentage of pixels (histogram)

EG: color=darkred]-histogram-stretch 5%[/color] would strecth the colors so as to peg the 5% brightest pixels and 5% darkest pixels to white and black.

Is that a fair summary? If so, I'll add it to the 'proposals page' and let Cristy know.
As for -normalize and channel. I'll update the IM Example description and IM documentation
to define what it is doing better.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
cra3y

Post by cra3y »

anthony wrote: EG: -histogram-stretch 5% would strecth the colors so as to peg the 5% brightest pixels and 5% darkest pixels to white and black.


all right 8)
anthony wrote: Is that a fair summary? If so, I'll add it to the 'proposals page' and let Cristy know.


Yes, that is, what i'm looking for
anthony wrote: As for -normalize and channel. I'll update the IM Example description and IM documentation
to define what it is doing better.


PS: this code below (in bash) do histogram stretch using levels:

Code: Select all

levels=""
function get_levels()
{
# how much pixels should be discarded in highlight/dark areas from scaled 1mpix image?
dark_thres=80
high_thres=240
#get 1mpix gray for luminance histogram meausure
convert "$1" -geometry 1280x960! -type grayscale -quality 95 histogram.jpg 2> /dev/null
# prepare data for histogram, natural sort by pixel value
# histogram.txt contains pixel count for each pixel value
convert histogram.jpg -format %c histogram:info:- 2> /dev/null |  gawk -F"[\t :#]+" '/[0-9]+\: /{printf ("%d %d\n",$2,(0"x"$4)/65536)}' | sort -nk2 > histogram.txt
# compute min parameter (leftmost)
min=$(gawk \
	'BEGIN{min=0;thres=('$dark_thres');to_thres=0;}
	{
	if(to_thres<thres){
		min=$2;
		to_thres+=$1;
		}
	}
	END{
	min=min-10;
	if(min<0){min=-2;}
	print ((min-1+1)*256);
	}' histogram.txt)
# compute max parameter (rightmost)
max=$(sort -nrk2 histogram.txt | gawk\
	'BEGIN{max=255;thres=('$high_thres');to_thres=0;}
	{
	if(to_thres<thres){
		max=$2;
		to_thres+=$1;
		}
	}
	END{
	print (max*256);
	}')
adjust_data=($min $max)
# if min = 0, get some space by shrink and move histogram to right
if [ ${adjust_data[0]} -le -2 ] ; then levels="-evaluate Multiply 0.99 -bias 620 -convolve 1 " ; adjust_data[0]=0 ; fi

# if max = 255, get some space by shrink and move histogram to left
if [ ${adjust_data[1]} -ge 65536 ] ; then levels=$adjust" -evaluate Multiply 0.99 " ; adjust_data[1]=65535 ; fi

# if min = 0 and max = 255, shrink histogram in both side
if [ ${adjust_data[0]} -eq ${adjust_data[1]} ] ; then levels="-evaluate Multiply 0.98 -bias 524 -convolve 1"
else levels=$adjust"-level "${adjust_data[0]}","${adjust_data[1]} ; fi

#show what we compute
echo $'('$((${adjust_data[0]}/256))'-'$((${adjust_data[1]}/256))')     '
# delete temporary file
rm -Rf histogram.jpg histogram.txt
}

get_levels "source_16bit.tif[0]"
convert source_16bit.tif[0] $levels +compress destination.tif
Post Reply