I'm working on an open source hardware project for a video/photo light, and it involves a fair bit of color math. I am trying to find my way from Color Temperature (CT) in Kelvin to current values used to drive the RGB LED's. I've struggled with this for quite a while now :-)
This is what I'm currently doing:
I take any CT value between 1800 and 15000 Kelvin and find the color coordinates. The CT is a value along the planchian locus of the CIE 1931 color space. I found a spline function here: http://en.wikipedia.org/wiki/Planckian_locus (the Approximation section). For a CT of 4000 I get x=0.380528339, y=0.376733566 and that looks correct to me.
Next I convert the xy coordinates to XYZ. I have semi-randomly set Y (brightness) to 0.6 to not saturate the LED current drivers.
Y = 0.6 X = x * (Y/y) Z = (1-x-y) * (Y/y)
Next, I do a matrix transformation. I take the CIE standard observer at the same wavelengths as the LED emitters:
Xbar 0.907244 0.1096 0.0579 Ybar 0.417036 0.7932 0.1693 Zbar 0.000220 0.0572 0.6162
I take a spectrometer reading of the individual LED emitters. The spectrometer gives me the CIE XYZ values for the Red, Green and Blue LEDs:
X 2.14 0.88 1.14 Y 0.95 2.7 0.59 Z -0.04 0.33 6.73
I found the MINVERSE() function in Excel to invert the LED XYZ readings. Then use MMULT() to multiply the CIE standard observer with the inverted LED XYZ, and I get:
0.8093637 -0.0775645 -0.1122626 0.0302540 0.7946191 -0.0104841 -0.0136168 0.0499041 0.1587569
So now I take the above array and multiply it by the XYZ values previously calculated from the Color Temperature:
R = (0.8093637 * X) + (-0.0775645 * Y) + (-0.1122626 * Z); G = (0.0302540 * X) + (0.7946191 * Y) + (-0.0104841 * Z); B = (-0.0136168 * X) + (0.0499041 * Y) + (0.1587569 * Z);
All this is supposed to transform the CT in CIE 1931 color space to the color response of the LED emitters.
But when I drive the LEDs with these RGB values, I get a compressed scale. 2000 K input measures as 4000 K. 15000 K input measures as 8000 K. I'm not really a math person and I can't for the life of me figure out where I go wrong!
EDIT: to clarify