NaN in XYZ->xyY conversion

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
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

NaN in XYZ->xyY conversion

Post by miket »

I'm sure this is NOT a bug, but simply the way the conversion is currently implemented :) (please feel free to relocate this post if you think appropriate).

Version: ImageMagick 7.0.5-0 Q16 x86_64 + Perl Magic + Linux

When converting from XYZ to xyY any pixels with X+Y+Z=0 values are converted to NaN (within Perl Magick). These need to be changed by the user to sensible values for onward processing.

In my own processing, I'm converting from XYZ to xyY - processing - then converting back to XYZ. I'm using ACES colour space so negative values of y can (and do) happen. Also processing in HDI so negative values of Y are possible (although I usually clamp these to zero).

It would be really useful if the conversion routine could resolve the NaN issue within the conversion.

The (veritable) Mr Lindbloom suggests that under these conditions the x & y values should be set to the color space white point (which may differ from file to file) and the Y value should be set to 0. http://www.brucelindbloom.com/index.htm ... atrix.html. In addition, when Y=0 then the current conversion results in y=0, which gives additional problems with the inverse conversion.

The inverse conversion has a singularity at y=0, again giving a NaN. Mr Lindbloom suggests under these conditions the result should be set to X=Y=Z=0.

However, when working with wide colorspaces (like ACES) which can have legitimate y=0 values (and non zero x & Y values) this solution may not be ideal. I'll think this one through more thoroughly when I've got some spare time. Perhaps the inverse transformation equations can be reworked to remove this singularity? Possibly the y=0 value should be "nudged" slightly to give a positive value? In the meantime X=Y=Z=0 is better than NaN.

Would it be possible for the wizards to implement this?

Alternatively, is there a computationally efficient way of removing the NaN's as suggested above using normal IM commands? I've tried creating an alpha mask then compositing a single value image with the original image and mask, which works, but is horrendously inefficient (I've 10,000's of big files to process).

Mike
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: NaN in XYZ->xyY conversion

Post by snibgo »

When I suggested the original code for xyY in magick\colorspace.c, I wondered about divide by zero when X+Y+Z==0, but it didn't seem to be a problem. And I can't construct a command-line example where it creates a problem, eg with v6.9.5-3:

Code: Select all

f:\web\im>%IM%convert xc:srgb(0,0,0) -set colorspace XYZ -colorspace xyY txt:

# ImageMagick pixel enumeration: 1,1,65535,xyy
0,0: (0,0,0)  #000000000000  xyy(0,0,0)
Can you show some code that illustrates the problem?
snibgo's IM pages: im.snibgo.com
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: NaN in XYZ->xyY conversion

Post by magick »

Can you post a URL to one or two images and the command-line you use to reproduce the NAN's? We'll use your image and command-line to verify our patches before we commit them to the next point release of ImageMagick.
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

I too tried to replicate the issue by command line (which I very rarely use) and could not replicate what I'm seeing using Perl Magic.

Will post an image & Perl code shortly to illustrate the issue.

Thanks

Mike
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

Hi,

Test code used

Code: Select all

    my $image = Image::Magick->new;
    my @pixel;
    open(IMAGE, 'r.png');
    $image->Read(file=>\*IMAGE);
    close(IMAGE);

    $image->SetPixel(x=>30, y=>30, color=>[0,0,0]);

    $image->Set(colorspace=>"RGB");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "RGB - $pixel[0] $pixel[1] $pixel[2]\n";

    $image->Colorspace(colorspace=>"XYZ");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "RGB->XYZ - $pixel[0] $pixel[1] $pixel[2]\n";

    $image->Colorspace(colorspace=>"xyY");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "XYZ->xyY - $pixel[0] $pixel[1] $pixel[2]\n";

    $image->Colorspace(colorspace=>"XYZ");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "xyY->XYZ - $pixel[0] $pixel[1] $pixel[2]\n";
Output showing NaN's generated in perl

Code: Select all

RGB - 0 0 0
RGB->XYZ - 0 0 0
XYZ->xyY - NaN NaN 0
xyY->XYZ - NaN NaN NaN

Test code for y = 0 in xyY space

Code: Select all

    my $image = Image::Magick->new;
    my @pixel;
    open(IMAGE, 'r.png');
    $image->Read(file=>\*IMAGE);
    close(IMAGE);



    $image->Set(colorspace=>"RGB");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "RGB - $pixel[0] $pixel[1] $pixel[2]\n";

    $image->Colorspace(colorspace=>"XYZ");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "RGB->XYZ - $pixel[0] $pixel[1] $pixel[2]\n";



    $image->Colorspace(colorspace=>"xyY");

    $image->SetPixel(x=>30, y=>30, color=>[.3,0,0.3]);


    @pixel = $image->GetPixel(x=>30, y=>30);
    print "XYZ->xyY - $pixel[0] $pixel[1] $pixel[2]\n";

    $image->Colorspace(colorspace=>"XYZ");
    @pixel = $image->GetPixel(x=>30, y=>30);
    print "xyY->XYZ - $pixel[0] $pixel[1] $pixel[2]\n";
Output

Code: Select all

RGB - 0.831372549019608 0.258823529411765 0.223529411764706
RGB->XYZ - 0.475787121147097 0.378041850251774 0.259344303139544
XYZ->xyY - 0.3 0 0.3
xyY->XYZ - NaN NaN NaN
snibgo
Posts: 12159
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: NaN in XYZ->xyY conversion

Post by snibgo »

@miket: Are you using HDRI? "convert -version" will say.

I can reproduce this at the command line, but only when HDRI is used. For example, using 6.9.0-0 Q16 HDRI:

Code: Select all

f:\web\im>%IM16f%convert xc:srgb(0,0,0) +write txt: -colorspace XYZ +write txt: -colorspace xyY txt:

# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (0%,0%,0%)  #000000000000  black
# ImageMagick pixel enumeration: 1,1,65535,xyz
0,0: (0%,0%,0%)  #000000000000  xyz(0,0,0)
# ImageMagick pixel enumeration: 1,1,65535,xyy
0,0: (nan%,nan%,0%)  #000000000000  xyy(nan%,nan%,0%)
snibgo's IM pages: im.snibgo.com
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

I'm using HDRI Version: ImageMagick 7.0.5-0 Q16 x86_64 + Perl Magic + Linux.
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

I think it would be sensible for the XYZ -> xyY conversion for the 0,0,0 XYZ situation to be mapped (as suggested by Lindbloom) to Y=0 and xy to be set to the whitepoint chromacities for the file (I'm not using sRGB, but ProPhoto and ACES which have different white point chromacities).

I still haven't had time to see if the xyY -> XYZ conversion can be re-arranged to resolve the y=0 singularity.

Mike
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: NaN in XYZ->xyY conversion

Post by magick »

Thanks for the problem report. We can reproduce it and will have a patch to fix it in GIT master branch @ https://github.com/ImageMagick/ImageMagick later today. The patch will be available in the beta releases of ImageMagick @ http://www.imagemagick.org/download/beta/ by sometime tomorrow.
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

Hi,

Updating IM to HDR ImageMagick 7.0.5-2 Q16 x86_64 2017-03-10 Beta appears to solve the NaN issue.

However, the fix appears to have introduced a problem with the xyY -> XYZ conversion on the X channel, which was not there before.

Doing a round trip RGB->XYZ->xyY->XYZ->RGB gives the following values.

RGB - 0.8 0.8 0.8
RGB->XYZ : 0.760376075284199 0.800000119211109 0.871064066433967
XYZ->xyY : 0.31272659051461 0.329023166294728 0.800000238422217
xyY->XYZ : 7.77497091248951 0.800001370927748 0.871064364461738
XYZ->RGB : 23.5304722667277 -5.99900577935454 1.19031588559548
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: NaN in XYZ->xyY conversion

Post by magick »

Our patch was not implemented properly. It should be ok now.
miket
Posts: 60
Joined: 2016-08-12T13:19:13-07:00
Authentication code: 1151

Re: NaN in XYZ->xyY conversion

Post by miket »

Thanks folks. This is working for me now :)
Post Reply