EXR data point accuracy
Posted: 2008-04-16T09:19:34-07:00
Hello all.
I am experimenting with the floating point image format EXR. I can write and read from the format, but I am getting horrible fidelity. I will present my results first and then attach my benchmark code at the end. I apologize in advance for the long post.
The attached code, exr_test.c, starts with a 3x3 array filled with the value 1.11111111. From there, it writes the values to an exr file and then reads the exr file. No explicit arithmetic is performed. Here are the results for a q8-HDRI build:
...for a q16-HDRI build...
and finally, for a q32-HDRI build:
So the error is constant in the 16 and 32 bit versions of IM. Additionally, small values such as 1E-3 disappear completely. So here is my question: is the error in the EXR coder, backup library or is it simply not spec'ed for true double precision floating point values?
Here is the test code:
I am experimenting with the floating point image format EXR. I can write and read from the format, but I am getting horrible fidelity. I will present my results first and then attach my benchmark code at the end. I apologize in advance for the long post.
The attached code, exr_test.c, starts with a 3x3 array filled with the value 1.11111111. From there, it writes the values to an exr file and then reads the exr file. No explicit arithmetic is performed. Here are the results for a q8-HDRI build:
Code: Select all
Benchmark Array: Read-in array: Difference:
[1.11111111 1.11111111 1.11111111 ] [1.11087799 1.11087799 1.11087799 ] [0.00023312 0.00023312 0.00023312 ]
[1.11111111 1.11111111 1.11111111 ] [1.11087799 1.11087799 1.11087799 ] [0.00023312 0.00023312 0.00023312 ]
[1.11111111 1.11111111 1.11111111 ] [1.11087799 1.11087799 1.11087799 ] [0.00023312 0.00023312 0.00023312 ]
Code: Select all
Benchmark Array: Read-in array: Difference:
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
Code: Select all
Benchmark Array: Read-in array: Difference:
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
[1.11111111 1.11111111 1.11111111 ] [1.10935807 1.10935807 1.10935807 ] [0.00175304 0.00175304 0.00175304 ]
Here is the test code:
Code: Select all
#include <stdlib.h>
#include <string.h>
#include <magick/MagickCore.h>
void snap( unsigned long x, unsigned long y, double *out, char *fname){
ExceptionInfo
*exception = AcquireExceptionInfo();
Image
*image;
unsigned long i,j;
MagickPixelPacket
pixel;
PixelPacket *q;
ImageInfo
*image_info= CloneImageInfo((ImageInfo *)NULL);
QueryMagickColor("black", &pixel, exception);
strcpy(image_info->filename, fname);
image = NewMagickImage(image_info, x, y, &pixel);
for(j = 0; j < 3; j++){
q = SetImagePixels(image, 0, j, 3, 1);
for(i = 0; i < 3; i++){
q->red = (Quantum)(out[i + 3 * j]);
q++;
}
if (SyncImagePixels(image) == MagickFalse)
break;
}
WriteImage(image_info, image);
}
int main(){
double test_arr[9] = { 1.234567E-2, 1.11111111, 1.11111111,
1.11111111, 1.11111111, 1.11111111,
1.11111111, 1.11111111, 1.11111111},
return_arr[9];
ExceptionInfo
*exception;
Image
*in;
ImageInfo
*info;
PixelPacket *q;
unsigned long i, j;
char fname[20];
MagickCoreGenesis(0,MagickTrue);
exception = AcquireExceptionInfo();
info = AcquireImageInfo();
sprintf(fname, "exr_test_%lu.exr", MAGICKCORE_QUANTUM_DEPTH);
snap(3,3, test_arr, fname);
strcpy(info->filename, fname);
in = ReadImage(info, exception);
for( j = 0; j < 3; j++){
q = GetImagePixels(in, 0, j, 3, 1);
for(i = 0; i < 3; i++){
return_arr[i + j * 3] =(double)q->red;
q++;
}
}
printf("\tBenchmark Array:\t\t\tRead-in array:\t\t\tDifference:\t\n");
for(i = 0; i < 3; i++){
printf("[");
for(j = 0; j < 3; j++){ printf("%1.8e ", test_arr[j + i*3]); }
printf("] [");
for(j = 0; j < 3; j++){ printf("%1.8e ", return_arr[j + i*3]); }
printf("] [");
for(j = 0; j < 3; j++){ printf("%1.8e ", test_arr[j + i*3] - return_arr[j + i*3]); }
printf("]\n");
}
return 0;
}