First, let me lay out what I’ve done so far and what I’m trying to do with this partially completed program.
I’m attempting to convert the RGB pixel values to their corresponding wavelength by:
Converting RGB to XYZ [check],
Converting XYZ to Yxy [check], and
Defining the dominant wavelength of xy [in progress].
The process of calculating the dominant wavelength of xy is laid out in [1,2]
and summarized as follows for my purposes:
'Construct a line between the chromaticity coordinates of the reference white point on the diagram [CIE-D65 --> x = 0.3127 , y = 0.3291] and the chromaticity coordinates [x1,y1 - in code below], and then extrapolate the line [via slopes] from the end that terminates at the filter point [graphed chromaticity curve].
The wavelength associated with the point on the horseshoe-shaped curve at which the extrapolated line intersects is the dominant wavelength.’
Essentially, the starting point x = 0.3127, y = 0.3291 is drawn to the RGB-converted x1, y1 point.
Then the slope, rise and run [slopeY, slopeX respectively] are calculated and followed until it intersects the horseshoe graph of the CIE 1931 2-deg, x,y chromaticity coordinates.
Here is where I’m having trouble. The horseshoe graph [picture above] of the “CIE x,y chromaticity coordinates, CIE 1931 2-deg chromaticity coordinates” which describe each corresponding wavelength are made up of many different points x,y and is listed here in CSV files [3].
[This annotated version I’m using is here, for clarity as to the x, y axis’]:
nm | x | y |
---|---|---|
360 | 0.17556 | 0.005294 |
365 | 0.175161 | 0.005256 |
370 | 0.174821 | 0.005221 |
375 | 0.17451 | 0.005182 |
380 | 0.174112 | 0.004964 |
385 | 0.174008 | 0.004981 |
390 | 0.173801 | 0.004915 |
395 | 0.17356 | 0.004923 |
400 | 0.173337 | 0.004797 |
405 | 0.173021 | 0.004775 |
410 | 0.172577 | 0.004799 |
415 | 0.172087 | 0.004833 |
420 | 0.171407 | 0.005102 |
425 | 0.170301 | 0.005789 |
430 | 0.168878 | 0.0069 |
435 | 0.166895 | 0.008556 |
440 | 0.164412 | 0.010858 |
445 | 0.161105 | 0.013793 |
450 | 0.156641 | 0.017705 |
455 | 0.150985 | 0.02274 |
460 | 0.14396 | 0.029703 |
465 | 0.135503 | 0.039879 |
470 | 0.124118 | 0.057803 |
475 | 0.109594 | 0.086843 |
480 | 0.091294 | 0.132702 |
485 | 0.068706 | 0.200723 |
490 | 0.045391 | 0.294976 |
495 | 0.02346 | 0.412703 |
500 | 0.008168 | 0.538423 |
505 | 0.003859 | 0.654823 |
510 | 0.01387 | 0.750186 |
515 | 0.038852 | 0.812016 |
520 | 0.074302 | 0.833803 |
525 | 0.114161 | 0.826207 |
530 | 0.154722 | 0.805864 |
535 | 0.192876 | 0.781629 |
540 | 0.22962 | 0.754329 |
545 | 0.265775 | 0.724324 |
550 | 0.301604 | 0.692308 |
555 | 0.337363 | 0.658848 |
560 | 0.373102 | 0.624451 |
565 | 0.408736 | 0.589607 |
570 | 0.444062 | 0.554714 |
575 | 0.478775 | 0.520202 |
580 | 0.512486 | 0.486591 |
585 | 0.544787 | 0.454434 |
590 | 0.575151 | 0.424232 |
595 | 0.602933 | 0.396497 |
600 | 0.627037 | 0.372491 |
605 | 0.648233 | 0.351395 |
610 | 0.665764 | 0.334011 |
615 | 0.680079 | 0.319747 |
620 | 0.691504 | 0.308342 |
625 | 0.700606 | 0.299301 |
630 | 0.707918 | 0.292027 |
635 | 0.714032 | 0.285929 |
640 | 0.719033 | 0.280935 |
645 | 0.723032 | 0.276948 |
650 | 0.725992 | 0.274008 |
655 | 0.728272 | 0.271728 |
660 | 0.729969 | 0.270031 |
665 | 0.731089 | 0.268911 |
670 | 0.731993 | 0.268007 |
675 | 0.732719 | 0.267281 |
680 | 0.733417 | 0.266583 |
685 | 0.734047 | 0.265953 |
690 | 0.73439 | 0.26561 |
695 | 0.734592 | 0.265408 |
700 | 0.73469 | 0.26531 |
705 | 0.73469 | 0.26531 |
710 | 0.73469 | 0.26531 |
715 | 0.734548 | 0.265452 |
720 | 0.73469 | 0.26531 |
725 | 0.73469 | 0.26531 |
730 | 0.73469 | 0.26531 |
735 | 0.73469 | 0.26531 |
740 | 0.73469 | 0.26531 |
745 | 0.73469 | 0.26531 |
750 | 0.73469 | 0.26531 |
755 | 0.73469 | 0.26531 |
760 | 0.73469 | 0.26531 |
765 | 0.73469 | 0.26531 |
770 | 0.73469 | 0.26531 |
775 | 0.73469 | 0.26531 |
780 | 0.73469 | 0.26531 |
785 | 0.73469 | 0.26531 |
790 | 0.73469 | 0.26531 |
795 | 0.73469 | 0.26531 |
800 | 0.73469 | 0.26531 |
805 | 0.73469 | 0.26531 |
810 | 0.73469 | 0.26531 |
815 | 0.73469 | 0.26531 |
820 | 0.73469 | 0.26531 |
825 | 0.73469 | 0.26531 |
830 | 0.73469 | 0.26531 |
I’m unsure of how to take all the x,y points in the CSV table [above] and algorithmically create the curve through which my line will intersect and output a specific wavelength.
How could I go about mapping the x,y chromaticity coordinates so that my slope-based line values [x_val, y_val] will intersect it and output the value?
float R2;
float G2;
float B2;
float X;
float Y;
float Z;
float x1;
float y1;
float z1;
float slopeY;
float slopeX;
float slope;
float lineX;
float lineY;
float x_val;
float y_val;
void setup() {
size(1024,768);
}
void draw() {
loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
// Total X-Y Pixel Array Scan
int loc = x+y*width;
float r = 0;
float g = 255;
float b = 162;
//Convert from RGB to XYZ
R2 = r/255;
G2 = g/255;
B2 = b/255;
if ( R2 > 0.04045 ) {
R2 = pow(( ( R2 + 0.055 ) / 1.055 ), 2.4);
}else{
R2 = R2 / 12.92;
}
if ( G2 > 0.04045 ) {
G2 = pow(( ( G2 + 0.055 ) / 1.055 ), 2.4);
}else{
G2 = G2 / 12.92;
}
if ( B2 > 0.04045 ){
B2 = pow(( ( B2 + 0.055 ) / 1.055 ), 2.4);
}else{
B2 = B2 / 12.92;
}
R2 = R2 * 100;
G2 = G2 * 100;
B2 = B2 * 100;
//Observer. = 2°, Illuminant = D65 [reference white]
X = R2 * 0.4124 + G2 * 0.3576 + B2 * 0.1805;
Y = R2 * 0.2126 + G2 * 0.7152 + B2 * 0.0722;
Z = R2 * 0.0193 + G2 * 0.1192 + B2 * 0.9505;
//println(X,Y,Z);
//Convert from XYZ to Yxy [chromaticity coordinates]
x1 = X / (X+Y+Z);
y1 = Y / (X+Y+Z);
z1 = 1 - (x1+y1); // thus, chromaticity coordinates are usually given as just x and y
//println(x1,y1);
//0.25991857, 0.45569262
//Calculate the dominant wavelength of xy
// construct a line between the chromaticity coordinates of the reference
// white point on the diagram (for instance, CIE-D65, CIE-E, CIEC, etc.)
// and the chromaticity coordinates [x1,y1], and then
// extrapolate the line from the end that terminates at the filter point
// The wavelength associated with the point on the horseshoe-shaped curve
// at which the extrapolated line intersects is the dominant wavelength.
// Reference White [Illuminant]
// CIE-D65 --> x = 0.3127 , y = 0.3291
lineX = 0.3127;
lineY = 0.3291;
// Chromaticity coordinates of filter [x1,y1],
x_val = x1; //0.25991857;
y_val = y1; //0.45569262;
// slopeY = [YA - YB]
// slopeX = [XA - XB]
slopeY = (lineY - y_val); // YB = Current xy point 0.45569262
slopeX = (lineX - x_val); // XB = Current xy point 0.25991857
slope = slopeY/slopeX; // -2.3984306
if (slope < 0){
while (x_val>0 && y_val>0){
x_val = x_val - slopeX;
y_val = y_val - slopeY;
}
if (x_val<0 || y_val<0){
x_val = x_val + slopeX;
y_val = y_val + slopeY;
}
} else {
}
//println(slope);
//println(x_val, y_val);
//float d = dist(width/2, height/2, x, y);
pixels[loc] = color(r, g, b);
}
}
updatePixels();
}
References:
Yxy Equations -
[1] https://www.semrock.com/how-to-calculate-luminosity-dominant-wavelength-and-excitation-purity.aspx
[2] https://www.hunterlab.se/wp-content/uploads/2012/11/Yxy-CIE-Chromaticity-Coordinates.pdf.
CIE 1931 2-deg, x,y chromaticity coordinates / Filter Points -
[3] http://www.cvrl.org/ccs.htm
CIE Basics-
http://hyperphysics.phy-astr.gsu.edu/hbase/vision/cie.html#c4