My goal is to convert an RGB pixel into CIELab color space for some special calculations only possible in CIELab. For this, I must convert RGB to XYZ first, which is the rea
As they said:
var_R = ( R / 255 ) -> var_R = ( R / 255.0 ) or var_R = ( R * 0.003922 )
var_G = ( G / 255 ) -> var_G = ( G / 255.0 ) or var_G = ( G * 0.003922 )
var_B = ( B / 255 ) -> var_B = ( B / 255.0 ) or var_B = ( B * 0.003922 )
This is because of implicit conversion. Despite the fact that var_R, var_G and var_B variables are float type, the / operator sees two integers R, G, B and 255. it has to divide and returns an integer.
In order to get a float type value you can do a CAST or convert at least one of the variables into float type adding of a decimal point as follows:
var_B = ( B / 255.0f)
Another example of RGB2LAB and LAB2RGB conversion (bear in mind that is CIE Lab D65):
void RGB2LAB(uint8_t R, uint8_t G, uint8_t B, float *l, float *a, float *b) {
float RGB[3], XYZ[3];
RGB[0] = R * 0.003922;
RGB[1] = G * 0.003922;
RGB[2] = B * 0.003922;
RGB[0] = (RGB[0] > 0.04045) ? pow(((RGB[0] + 0.055)/1.055), 2.4) : RGB[0] / 12.92;
RGB[1] = (RGB[1] > 0.04045) ? pow(((RGB[1] + 0.055)/1.055), 2.4) : RGB[1] / 12.92;
RGB[2] = (RGB[2] > 0.04045) ? pow(((RGB[2] + 0.055)/1.055), 2.4) : RGB[2] / 12.92;
XYZ[0] = 0.412424 * RGB[0] + 0.357579 * RGB[1] + 0.180464 * RGB[2];
XYZ[1] = 0.212656 * RGB[0] + 0.715158 * RGB[1] + 0.0721856 * RGB[2];
XYZ[2] = 0.0193324 * RGB[0] + 0.119193 * RGB[1] + 0.950444 * RGB[2];
*l = 116 * ( ( XYZ[1] / 1.000000) > 0.008856 ? pow(XYZ[1] / 1.000000, 0.333333) : 7.787 * XYZ[1] / 1.000000 + 0.137931) - 16;
*a = 500 * ( ((XYZ[0] / 0.950467) > 0.008856 ? pow(XYZ[0] / 0.950467, 0.333333) : 7.787 * XYZ[0] / 0.950467 + 0.137931) - ((XYZ[1] / 1.000000) > 0.008856 ? pow(XYZ[1] / 1.000000, 0.333333) : 7.787 * XYZ[1] / 1.000000 + 0.137931) );
*b = 200 * ( ((XYZ[1] / 1.000000) > 0.008856 ? pow(XYZ[1] / 1.000000, 0.333333) : 7.787 * XYZ[1] / 1.000000 + 0.137931) - ((XYZ[2] / 1.088969) > 0.008856 ? pow(XYZ[2] / 1.088969, 0.333333) : 7.787 * XYZ[2] / 1.088969 + 0.137931) );
}
void LAB2RGB(float L, float A, float B, uint8_t *r, uint8_t *g, uint8_t *b) {
float XYZ[3], RGB[3];
XYZ[1] = (L + 16 ) / 116;
XYZ[0] = A / 500 + XYZ[1];
XYZ[2] = XYZ[1] - B / 200;
XYZ[1] = (XYZ[1]*XYZ[1]*XYZ[1] > 0.008856) ? XYZ[1]*XYZ[1]*XYZ[1] : (XYZ[1] - (16 / 116)) / 7.787;
XYZ[0] = (XYZ[0]*XYZ[0]*XYZ[0] > 0.008856) ? XYZ[0]*XYZ[0]*XYZ[0] : (XYZ[0] - (16 / 116)) / 7.787;
XYZ[2] = (XYZ[2]*XYZ[2]*XYZ[2] > 0.008856) ? XYZ[2]*XYZ[2]*XYZ[2] : (XYZ[2] - (16 / 116)) / 7.787;
RGB[0] = 0.950467 * XYZ[0] * 3.2406 + 1.000000 * XYZ[1] * -1.5372 + 1.088969 * XYZ[2] * -0.4986;
RGB[1] = 0.950467 * XYZ[0] * -0.9689 + 1.000000 * XYZ[1] * 1.8758 + 1.088969 * XYZ[2] * 0.0415;
RGB[2] = 0.950467 * XYZ[0] * 0.0557 + 1.000000 * XYZ[1] * -0.2040 + 1.088969 * XYZ[2] * 1.0570;
*r = (255 * ( (RGB[0] > 0.0031308) ? 1.055 * (pow(RGB[0], (1/2.4)) - 0.055) : RGB[0] * 12.92 ));
*g = (255 * ( (RGB[1] > 0.0031308) ? 1.055 * (pow(RGB[1], (1/2.4)) - 0.055) : RGB[1] * 12.92 ));
*b = (255 * ( (RGB[2] > 0.0031308) ? 1.055 * (pow(RGB[2], (1/2.4)) - 0.055) : RGB[2] * 12.92 ));
}