HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

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.
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

Hello!

I know this is an exotic topic, and anyway, it's not exactly a bug, but I noticed a statistic bias in the HDRI enabled version....

I was doing statistics on differences between 8bit and 16bit versions of the same image, to find the standard deviation of the sampling error (should be about 1/1024, and it is), and I found some weird results while using the HDRI version to convert between the 16bit source file and the 8bit file.

The 16bit integer version seems to work fine, with minimal statistical bias. The HDRI version introduces a bias of half-a-sample in the conversion. Both versions are consistent, in that converting 8->16->8 produces the same file both using only HDRI and integer versions and also mixing them. The inconsistency only occurs in the conversion of original 16 bits (really containing 16 bits precision) files into 8 bit files.

Here are the statistics for the 16 bits integer version:

channel;minimum;maximum;average;avgdiff;inv_avgdiff
0;-1.95318E-3;+1.95315E-3;-1.34887E-6;+9.46763E-4;+1.05623E3
1;-1.95318E-3;+1.95315E-3;-9.19341E-7;+9.69026E-4;+1.03196E3
2;-1.95318E-3;+1.95315E-3;-8.85847E-7;+9.69657E-4;+1.03129E3

And for the HDRI version:

channel;minimum;maximum;average;avgdiff;inv_avgdiff
0;+0.00000E0;+3.90631E-3;+2.02278E-3;+1.01292E-3;+9.87250E2
1;+0.00000E0;+3.90631E-3;+1.97609E-3;+9.91682E-4;+1.00839E3
2;+0.00000E0;+3.90631E-3;+1.97442E-3;+9.91065E-4;+1.00902E3

This are the statistics for the 16bit.ppm minus the 8bit.ppm, so the bias makes the 8 bit image 1/500 (half a sample) darker.

I did the difference and statistics myself, on a small program I made in java. It converts the interval 0-255 to 0.0-1.0 and 0-65535 into 0.0-1.0 both into an array of floats. Then subtract both arrays and proceed to calculate the statistics in double precision.

The input images were raw photographs converted into 16 bit ppm at an earlier stage, then converted into 8bit.ppm using the 16bit integer ImageMagick and then the HDRI enabled ImageMagick.

Just to clarify the meaning of the columns:

channel: the number of the ppm channel, 0=R, 1=G, 2=B

minimum: the value of the minimum in the differences

maximum: the value of the maximum in the differences

average: the average of the differences, this should tend to zero ideally.

avgdiff: the standard deviation of the differences

inv_avgdiff: the inverse of the standard deviation of the differences (a.k.a. signal to noise ratio)

I don't really know if this is an error... or something I'm interpreting badly. It happens with all photos I tried. I don't even know if I explained myself well :?

If you need any help to uncover this... the program I used to gather the statistics, for example... just ask. It's trivial code, but nevertheless...
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by fmw42 »

try the pfm or tiff or miff format as it supports 32-bit floats to fractions rather than 32-bit integers. see if you still see the problem
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

I've nailed it, using a small 12 pixel pgm...

The conversion from 8-->16 is consistent:

input_8bits;hdri_16bits;int_16bits
0;0;0
1;257;257
255;65535;65535

But look at what happens from 16-->8...

input_16bits;hdri_8bits;int_8bits
0;0;0
1;0;0
126;0;0
127;0;0
128;0;0
129;0;1
254;0;1
255;0;1
256;0;1
257;1;1
65534;254;255
65535;255;255

The HDRI version truncates, instead of rounding.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by fmw42 »

it is likely your image format. hdri is not expecting to do either -- round or truncate. it is expecting to hold the fraction if the right image format is used, such as pfm, tiff or miff. pgm does not support 32-bit floats as far as I know. you need pfm or tiff or miff.

I would again suggest you try the same experiment with one (or all) of these formats and see what happens. You could very well be right. But to test fully, you need to use a format that supports the objective of HDRI.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by magick »

For most algorithms, HDRI is not clamped or rounded because it can go negative or exceed the quantum range. You can always add -clamp to your command line before you write to PGM. We could automatically clamp for non-HDRI images such as PGM but only if Fred agrees thats the right thing to do.
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

fmw42, this is not a bug in reading or manipulating high depth images. HDRI-enabled imagemagick works just fine with OpenEXR for example.

I wouldn't even call it a bug... It's a statistically-unsound choice (truncate instead of round) in converting from high depth into low depth. It generates a bias that tends to darken images, even if slightly. And is inconsistent with what the original (integer) version does.

This is a minor issue really, but it's there :)

Just to clarify, if you convert from an unsigned integer into a float, this it the correct way:

double divisor = pow(2.0d,(double)bit_depth)-1.0d; // 65535.0d for 16 bits, 255.0d for 8 bits
double sample = ((double)input_value)/divisor;

And from double into integer:

double divisor = pow(2.0d,(double)bit_depth)-1.0d; // 65535.0d for 16 bits, 255.0d for 8 bits
double aux = round(sample*divisor);
if (aux>divisor) aux=divisor;
if (aux<0) aux=0;
int output_value = (int)aux;
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

Sorry, I was editing my last post while you posted back...

Anyway, -clamp won't solve this bias.

I think you shouldn't add clamp: that would defeat the purpose of HDRI. This only applies when you're writing into or reading from an integer image format. It is at that exact time that the conversion rules I wrote apply, and if you follow them the bias will disappear.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by fmw42 »

It would appear that rnbc seems to feel that it should round rather than clamp or truncate in order to be consistent with non-HDRI modes. So if something is to be done, I would suggest an equivalent function to -clamp (to be added to the command line) to do the rounding so that he gets consistent values with non-hdri support formats. Or go ahead an insert the round into HDRI compilations, BUT only for non-hdri supported formats. The problem is I don't know all the hdri formats (ones that support full 32-bit float including negative values other than MIFF, MPC MPR?, TIFF and PFM. EXR is only half - 16-bit. Are there other full 32-bit formats?). I am open to further suggestions or discussion.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by anthony »

If you want a HDRI rounding function I would make it a separate function to -clamp

I noted that -clamp did not produce the same results as a non-HDRI version in IM examples..
Clamp to Enforcing image bounds in HDRI
http://www.imagemagick.org/Usage/basics/#clamp
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by fmw42 »

anthony wrote:If you want a HDRI rounding function I would make it a separate function to -clamp

I noted that -clamp did not produce the same results as a non-HDRI version in IM examples..
Clamp to Enforcing image bounds in HDRI
http://www.imagemagick.org/Usage/basics/#clamp
Yes, that was my first suggestion -- a separate rounding function. But clamping may still be necessary to avoid overflow or underflow?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by anthony »

the integer Image formats I believe automatically clamp when the values are out of range.
It is only a rounding problem that needs to be figured out.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by fmw42 »

OK, thanks for the clarification
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

anthony wrote:the integer Image formats I believe automatically clamp when the values are out of range.
It is only a rounding problem that needs to be figured out.
I think you're right.

In fact the conversion from 8->16 bits already works fine in both versions, correctly using the rule:

y=65535/255*x

It is the other way around that is introducing a bias, probably not in the floating point pipeline, that seems to work just fine, but in some conversion to integers, probably when writing the file.
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by magick »

We'll have a fix for this problem within a week. Thanks.
rnbc
Posts: 109
Joined: 2010-04-11T18:27:46-07:00
Authentication code: 8675308

Re: HDRI - Statistic bias in convertion16bit.ppm to 8bit.ppm

Post by rnbc »

While not being exactly equivalent to the conversion being done in the integer version this new hdri version in actually more accurate:

16bit,8bit_int,8bit_hdri
0,0,0
1,0,0
126,0,0
127,0,0
128,0,0
129,1,1
254,1,1
255,1,1
256,1,1
257,1,1
65406,254,254
65407,255,254
65408,255,255
65409,255,255
65534,255,255
65535,255,255

This small difference in conversion (in the middle values above 32767) lowers the standard deviation of the error in the 8bit encoding from 1/883 to 1/886 in some quantum intervals (it's like going from quantum_error=1/255 to quantum_error=1/256 in some intervals).

For those that might care this comes from the formula of stddev of the uniform distribution:

1/sqrt(12*255^2)=1/883

1/sqrt(12*256^2)=1/886

And I just checked with a few images: the stddev error indeed went a bit down in some images, although the maximum errors went a bit up, but overall it's a gain over the integer version, even if smallish :)

You did a great job as usual guys!
Post Reply