Convert manually CIE LChab values to RGB

205 Views Asked by At

I want display sRGB values based on CIE LHab values, i didn't really know the topic aroud color theory but here is my code, i use colour library. Did i miss something?

#Use Illuminant d65 
d65 = [0.31382,0.33100]
# Maximun lightness of 100
lightess = 100
# Maximun chroma of 90
chroma = 90
# Create primary hue
hue = np.arange(0,360,45)

# Create np array
primary_rgb = np.array([[lightess,chroma, x] for x in hue])
# Convert to CIE L*a*b
primary_lab = colour.LCHab_to_Lab(primary_rgb) 
# Convert to XYZ 
primary_xyz =  colour.Lab_to_XYZ(primary_lab)
# Convert to sRGB color
primary_rgb = colour.XYZ_to_sRGB(primary_xyz,d65,'Bradford')
# Denormalize values 
primary_rgb*255

Output out of range with negative values...

 array([[  409.91335532,   170.93938038,   260.71868158],
       [  393.03002494,   198.83037084,   134.96104706],
       [  300.27298956,   250.59731666,    58.49528246],
       [  157.31758891,   283.79165255,   123.85945153],
       [-1256.38350547,   296.51665099,   254.2577884 ],
       [-2417.70063864,   292.21019209,   380.58920247],
       [ -374.81508589,   264.85047515,   434.59056034],
       [  315.68646752,   211.99574857,   383.26874897]])

I want a correct ouput

1

There are 1 best solutions below

2
Kel Solaar On

The problem here is that you are constructing a hue sweep that covers a significant portion of the CIE Lab space, doing so, some of the colours, i.e. the negative ones, will be outside sRGB gamut:

import colour
import numpy as np

D65 = colour.CCS_ILLUMINANTS["CIE 1964 10 Degree Standard Observer"]["D65"]
hue = np.arange(0, 360, 45)
LCHab = colour.utilities.tstack([np.full(hue.shape, 100), np.full(hue.shape, 90), hue])
Lab = colour.LCHab_to_Lab(LCHab)
XYZ = colour.Lab_to_XYZ(Lab, D65)
sRGB = (
    colour.cctf_encoding(
        np.clip(colour.XYZ_to_sRGB(XYZ, apply_cctf_encoding=False), 0, 1)
    )
    * 255
)

print(sRGB)

figure, axes = colour.plotting.plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS(
    "sRGB", diagram_opacity=0.25, standalone=False
)
uv = colour.Luv_to_uv(colour.XYZ_to_Luv(XYZ, D65))
axes.scatter(uv[..., 0], uv[..., 1])
colour.plotting.render()

Hue Sweep