[argyllcms] Re: Convert CIE xy chromaticities to some RGB

  • From: "Richard Kirk" <dmarc-noreply@xxxxxxxxxxxxx> (Redacted sender "richard" for DMARC)
  • To: argyllcms@xxxxxxxxxxxxx
  • Date: Sun, 14 Apr 2019 10:56:25 +0100

This is weird. 

I got a program for clipping colours in an arbitrary space to a spectral locus 
last night. Now, this isn’t quite what you are after, but I might as well chip 
in my bit…

If you take an equal  unit of each wavelength in SI units

400nm  Yxy =  108.728 cd/m2  0.17334  0.00480   
410nm  Yxy =  332.225 cd/m2  0.17258  0.00480   
420nm  Yxy =  1098.26 cd/m2  0.17141  0.00510   
430nm  Yxy =  3184.97 cd/m2  0.16888  0.00690   
440nm  Yxy =  6315.02 cd/m2  0.16441  0.01086   
450nm  Yxy =  10433.5 cd/m2  0.15664  0.01770   
460nm  Yxy =  16474.0 cd/m2  0.14396  0.02970   
470nm  Yxy =  24980.0 cd/m2  0.12412  0.05780   
480nm  Yxy =  38170.2 cd/m2  0.09129  0.13270   
490nm  Yxy =  57115.2 cd/m2  0.04539  0.29498   
500nm  Yxy =  88684.8 cd/m2  0.00817  0.53842   
510nm  Yxy =  138107. cd/m2  0.01387  0.75019   
520nm  Yxy =  194942. cd/m2  0.07430  0.83380   
530nm  Yxy =  236676. cd/m2  0.15472  0.80586   
540nm  Yxy =  261936. cd/m2  0.22962  0.75433   
550nm  Yxy =  273179. cd/m2  0.30160  0.69231   
560nm  Yxy =  273193. cd/m2  0.37310  0.62445   
570nm  Yxy =  261387. cd/m2  0.44406  0.55471   
580nm  Yxy =  238872. cd/m2  0.51249  0.48659   
590nm  Yxy =  207846. cd/m2  0.57515  0.42423   
600nm  Yxy =  173251. cd/m2  0.62704  0.37249   
610nm  Yxy =  138107. cd/m2  0.66576  0.33401   
620nm  Yxy =  104610. cd/m2  0.69150  0.30834   
630nm  Yxy =  72760.0 cd/m2  0.70792  0.29203   
640nm  Yxy =  48049.0 cd/m2  0.71903  0.28093   
650nm  Yxy =  29378.6 cd/m2  0.72599  0.27401   
660nm  Yxy =  16748.5 cd/m2  0.72997  0.27003   
670nm  Yxy =  8786.11 cd/m2  0.73199  0.26801   
680nm  Yxy =  4667.62 cd/m2  0.73342  0.26658   
690nm  Yxy =  2254.19 cd/m2  0.73439  0.26561   
700nm  Yxy =  1126.27 cd/m2  0.73469  0.26531   


You can see this peaks at 555 nm as it should. However, the Y value is not a 
great measure of how bright it appears to you. Also the contrast is huge so 
your 430 nm violet will be hard to see.

Another problem is the standard tables of the CIE values give the weights as 
ASCII numbers, so they lose precision when the numbers get very small.

I imagine you are mentally drawing Iines between your 430nm point and your 
white point in an (x,y) diagram, and seeing where it intercepts the locus. 

Let me suggest a very different route for plotting a spectrum. This may not be 
what you want to do, but bear with me for now…

I remember seeing what someone claimed to be an accurate representation of the 
spectrum in CMYK and not being very impressed with it. Too much yellow, too 
much cyan, as I recall. You phrased your question in terms of RGB so I am going 
to assume you have an RGB projector and you can scale your RGB values to vary 
the brightness. If you are printing in CMYK then you can add K to vary the 
brightness.

Suppose you are looking at your colour gamut down the luminance axis. The most 
saturated colours you can get will be bounded by the colour corners of your RGB 
cube. The most saturated colours you can get will be somewhere on the  
R-Y-G-C-B-M circuit. Some of the B_M_R segment won’t be on the spectrum, but 
all the spectral colours will be approximated in there somewhere.

This circuit has a brightness that goes up and down, as you go from 1 to 2 
primaries. The saturation also goes in and out. You will also probably want to 
shape the intensity so the extreme reds and violets go to black. You way not 
want to do this exactly according to the CIE Y weights as this will make the 
blues very dark.

Suppose you start off with a 1-D set of RGB values that cover the R-Y-G-C-B-M 
circuit.

Calculate the hue angle out from white, do that, and replace everything that is 
outside your wavelength range with black.

Do a 1D convolution of these values with some smooth function such as a 
Gaussian with a half-height width of (say) 40nm. This will smooth out much of 
the discontinuity at the R-Y-G-C-B-M corners. This will reduce the saturation 
of colours such as the primary green, but this is a good thing as they were 
sticking out too far anyhow. I don’t think you want to reduce everything to a 
perfect circle in (x,y) but a bit of rounding off won’t hurt.

You will now have a smooth set of points that will lie on your spectrum, except…
- the wavelength scale is unknown.
- the brightness is arbitrary.

The wavelength scale is probably not far off uniform, if you remember the 
geometry when projecting to the white point. Perhaps imagine it in u’v’ instead 
as that is less distorted (though the result should be the same).
 
The spectrum will go dark at either extreme in a realistic manner. It won’t be 
an exact match to the CIE standard, but an exact match would depend on your 
white and the reference spectrum you are trying to simulate. And, for the 
violets, the difference between D65 and 6500K blackbody will be big. And your 
projector colours are probably a long way away from the spectral locus, so 
there is a lot of leverage in your (x,y) plot geometry. 

If this spectrum doesn’t look right to you, then at least we reduced things 
from a 3D problem to a 1D one, so you might be able to tweak it from there.

Okay, that’s not what you asked fr, and I know it. But if you can follow these 
steps, you can perhaps see why there is not necessarily a single answer to 
“What is the RGB for 430nm light?”.

Or you could get your projector to project a white line, and use a diffraction 
grating...

Hope this helps a bit.

Cheers
Richard Kirk

Other related posts: