Potential issue with CIE L*a*b colour space conversion to RGB

I wonder whether there is an issue when converting between CIE Lab space and the -1:1 RGB space of PsychoPy.

I am setting my stimulus colour from the CIE Lab colour space. In PsychoPy, LAB parameters are converted to RGB (range -1 to 1) which is then used to set the colour of the stimuli. To do this conversion, I am using the cielab2rgb function to take the LAB parameters and return RGB as set out in the example pages here (see also below):

import psychopy.tools.colorspacetools as cst
cielabColor = (53.0, -20.0, 0.0)  # greenish color (L*, a*, b*)
rgbColor = cst.cielab2rgb(cielabColor)

This returns the RGB values (-0.82339714, -0.50600726, -0.58329596)

To test this conversion function was accurate before usage, I used this website to get LAB parameters for an RGB value of (0.5, 0.5, 0.5) from 0–1 space. As PsychoPy uses -1 to 1 space for RGB, this pertains to an RGB value of (0, 0, 0).

To get such an RGB value, the required LAB parameters are L = 53.389, a* = 0.00, b* = 0.00.

I was interested in whether if when I enter these LAB parameters into the cielab2rg function it returns (0.00, 0.00, 0.00). However, when I run the code below:

import psychopy.tools.colorspacetools as cst
cielabColor = (53.389, 0.0, 0.0)  
rgbColor = cst.cielab2rgb(cielabColor)
print(rgbColor)

I get RGB values of (-0.57184359, -0.57184359, -0.57184359). To rescale these back into the RGB range of 0-1, this pertains to (with some rounding) RGB values of (0.214, 0.214, 0.214), which is quite a way off the “generating” RGB values of (0.5, 0.5, 0.5).

Is there an error in the cielab2rgb function, or is there something awry with my understanding of colour spaces?

Thanks,
Jim

Hello Jim,

Is there an error in the cielab2rgb function, or is there something awry with my understanding of colour spaces?

Probably neither in this case. However the CIELAB function is a little confusing to use (one of the reasons it was not made an official colorspace yet). You need to specify a transfer function for sRGB gamma correction.

cielabColor = (53.389, 0.0, 0.0)
rgbColor = cst.cielab2rgb(cielabColor, transferFunc=cst.srgbTF)

You should get values very close to zero which should rescale to close to 0.5.

I would also recommend the colour python package for doing this stuff: https://www.colour-science.org/

1 Like

So, ultimately the issue is the fact that CIElab is a device-independent color space. The colors on one device should match the specified colors on another device. For that to be possible we have to know the tristimulus coordinates (the location in the space) for one or more points that can be used for the conversion (either the value of white, or the value of each gun at its max). Ideally this should be measured for your own device. If not then some default value will be used and the choice of what you set as the default value will determine the numbers being output.

BUT it could also be an incorrect scale value so I’d have to check! :wink:

There is a function in monitors.calibTools called makeXYZ2RGB that helps create these conversion matrices from measured RGB chromaticity coordinates which can be used with cielab2rgb.

1 Like

Thank you! This sorted the issue.