O que há de errado com este algoritmo de conversão de espaço de cores RGB para XYZ?

Meu objetivo é converter um pixel RGB no espaço de cores CIELab para alguns cálculos especiais possíveis apenas no CIELab. Para isso, devo primeiro converter RGB em XYZ, que é a parte mais difíci

Tentei implementar esse algoritmo no Objective-C (porém usando C simples), mas os resultados estão errado

Meu código é baseado na pseudo-implementação fornecida por easyrgb.com. Eles têm um conversor de cores on-line que funciona muito bem. Eles dizem que o pseudocódigo é o mesmo usado no converso

Este é o seu pseudo-có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

Esta é minha tentativa de implementá-lo no 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;
}

No entanto, não obtenho os mesmos resultados que sua ferramenta (com a mesma configuração de Observador e Iluminante

No meu teste, inseri esses valores na ferramenta e obtive esse resultado para o XYZ, que está muito longe do que minha implementação produz para esse valor RGB. Por favor, veja a captura de tela:

Os valores de cores resultantes do laboratório estão muito próximos do que o Photoshop me diz, portanto o conversor funciona muito be

O código C acima me dá esses resultados:

X = 35.76... // should be 42.282
Y = 71.52... // should be 74.129
Z = 11.92... // should be 46.262

Alguma idéia de qual é a causa desse fracasso? Cometi um erro na minha implementação ou preciso de outras constantes?

Se você conhece algumas implementações de RGB para XYZ, XYZ para CIELab ou RGB para CIELab, XYZ para Lab ou RGB para Lab, não hesite em publicá-las aqu

Basicamente, tudo o que quero fazer é calcular o desvio entre duas cores, também conhecido como Delta-E. É por isso que preciso converter de RGB para XYZ em laboratório (ou CIELab) ...

questionAnswers(6)

yourAnswerToTheQuestion