Question

I am trying to convert an image from RGB to XYZ using scikit-image. I found out that there are some differences depending the input type:

from numpy import array,uint8
import skimage.color

rgb = array([array([[56,79,132],[255,100,70]])]) 
i1 = skimage.color.rgb2xyz(rgb)#rgb.dtype ->dtype('int32')
i2 = skimage.color.rgb2xyz(rgb.astype(uint8))
i3 = skimage.color.rgb2xyz(rgb.astype(float))

print i1[0,1,:]
print i2[0,1,:]
print i3[0,1,:]

This is the output:

[  5.55183419e-09   4.73226247e-09   3.02426596e-09]
[ 0.46907236  0.3082294   0.09272133]
[ 240644.54537677  153080.21825017   39214.47581034]

The cause of the differences is the function img_to_float which is used inside rgb2xyz (see this question).

But I am wondering: What is the correct way to use rgb2xyz?

Regarding this question there are multiple solutions, depending on the formula, but again: what is the correct image type that is required by rgb2xyz? It seems that unit8, but why? Thanks!

Was it helpful?

Solution

The following code should be self explanatory, but floating point values should have a range in (0, 1), and integer type have their full range mapped to (0, 1) (for unsigned types) or (-1, 1) (for signed types):

>>> from numpy import int32
>>> skimage.color.rgb2xyz((rgb / 255 * (2**31 - 1)).astype(int32))
array([[[ 0.08590003,  0.08097913,  0.2293394 ],
        [ 0.46907236,  0.3082294 ,  0.09272133]]])
>>> skimage.color.rgb2xyz(rgb.astype(uint8))
array([[[ 0.08590003,  0.08097913,  0.2293394 ],
        [ 0.46907236,  0.3082294 ,  0.09272133]]])
>>> skimage.color.rgb2xyz(rgb.astype(float) / 255)
array([[[ 0.08590003,  0.08097913,  0.2293394 ],
        [ 0.46907236,  0.3082294 ,  0.09272133]]])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top