¿Qué tiene de malo este algoritmo de conversión de espacio de color RGB a XYZ?
Mi objetivo es convertir un píxel RGB en espacio de color CIELab para algunos cálculos especiales que solo son posibles en CIELab. Para esto, primero debo convertir RGB a XYZ, que es la parte realmente difícil.
Traté de implementar este algoritmo en Objective-C (aunque principalmente usando C simple), pero los resultados son incorrectos.
Mi código se basa en la pseudo-implementación proporcionada por easyrgb.com. Tienen un convertidor de color en línea que funciona muy bien. Dicen que su pseudocódigo es el mismo utilizado en su convertidor.
Este es su pseudocódigo:
var_R = ( R / 255 ) //R from 0 to 255
var_G = ( G / 255 ) //G from 0 to 255
var_B = ( B / 255 ) //B from 0 to 255
if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
else var_R = var_R / 12.92
if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
else var_G = var_G / 12.92
if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
else var_B = var_B / 12.92
var_R = var_R * 100
var_G = var_G * 100
var_B = var_B * 100
//Observer. = 2°, Illuminant = D65
X = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
Y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
Z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
Este es mi intento de implementarlo en Objective-C / C:
void convertRGBtoXYZ(NSInteger * inR, NSInteger * inG, NSInteger * inB, CGFloat * outX, CGFloat * outY, CGFloat * outZ) {
// http://www.easyrgb.com/index.php?X=MATH&H=02#text2
CGFloat var_R = (*inR / 255); //R from 0 to 255
CGFloat var_G = (*inG / 255); //G from 0 to 255
CGFloat var_B = (*inB / 255); //B from 0 to 255
if (var_R > 0.04045f) {
var_R = powf(( (var_R + 0.055f) / 1.055f), 2.4f);
} else {
var_R = var_R / 12.92f;
}
if (var_G > 0.04045) {
var_G = powf(( (var_G + 0.055f) / 1.055f), 2.4f);
} else {
var_G = var_G / 12.92f;
}
if (var_B > 0.04045f) {
var_B = powf(( (var_B + 0.055f) / 1.055f), 2.4f);
} else {
var_B = var_B / 12.92f;
}
var_R = var_R * 100;
var_G = var_G * 100;
var_B = var_B * 100;
//Observer. = 2°, Illuminant = D65
*outX = var_R * 0.4124f + var_G * 0.3576f + var_B * 0.1805f;
*outY = var_R * 0.2126f + var_G * 0.7152f + var_B * 0.0722f;
*outZ = var_R * 0.0193f + var_G * 0.1192f + var_B * 0.9505f;
}
Sin embargo, no obtengo los mismos resultados que su herramienta (con la misma configuración de Observador e Iluminante).
En mi prueba, ingresé estos valores en su herramienta y obtuve este resultado para XYZ, que está muy lejos de lo que mi implementación produce para ese valor RGB. Por favor, vea la captura de pantalla:
os valores de color de Lab resultantes son bastante parecidos a los que Photoshop me dice, por lo que el convertidor funciona muy bie
Sin embargo, el código C anterior me da estos resultados:
X = 35.76... // should be 42.282
Y = 71.52... // should be 74.129
Z = 11.92... // should be 46.262
¿Alguna idea de cuál es la causa de este fracaso? ¿Cometí un error en mi implementación o necesito otras constantes?
Si conoce algunas implementaciones probadas de RGB a XYZ, XYZ a CIELab o RGB a CIELab, XYZ a Lab o RGB a Lab, no dude en publicarlas aquí.
Básicamente, todo lo que quiero hacer es calcular la desviación entre dos colores, también conocido como Delta-E. Es por eso que necesito convertir de RGB a XYZ a Lab (o CIELab) ...