RGB 实验室结果相互矛盾

问题描述 投票:0回答:1

我的代码正处于十字路口,说实话,我不太确定发生了什么......这可能很明显,但我看不出问题出在哪里。

我正在尝试将 RGB 转换为 XYZ 到 Lab,到目前为止,R(X) 和 G(Y) 部分似乎一切正常,但我无法查明 B(Z) 的错误,它是让我发疯。

这是我的代码,我使用的是 2 Degree D50

void SearchColour()
{ 
    double[] xyz = new double[3];
    double[] lab = new double[3];
    double[] rgb = new double[3];
    rgb[0] = searchColourr / 255.0d;
    rgb[1] = searchColourg / 255.0d;
    rgb[2] = searchColourb / 255.0d;
    if (rgb[0] > .04045d)
    {
        rgb[0] = Math.Pow((rgb[0] + .055d) / 1.055d, 2.4d);
    }
    else
    {
        rgb[0] = rgb[0] / 12.92d;
    }
    if (rgb[1] > .04045d)
    {
        rgb[1] = Math.Pow((rgb[1] + .055d) / 1.055d, 2.4d);
    }
    else
    {
        rgb[1] = rgb[1] / 12.92d;
    }
    if (rgb[2] > .04045d)
    {
        rgb[2] = Math.Pow((rgb[2] + .055d) / 1.055d, 2.4d);
    }
    else
    {
        rgb[2] = rgb[2] / 12.92d;
    }
    //D50 sRGB working space
    xyz[0] = ((rgb[0] * 0.4360747d) + (rgb[1] * 0.3850649d) + (rgb[2] * 0.1430804d));
    xyz[1] = ((rgb[0] * 0.2225045d) + (rgb[1] * 0.7168786d) + (rgb[2] * 0.0606169d));
    xyz[2] = ((rgb[0] * 0.0139322d) + (rgb[1] * 0.0971045d) + (rgb[2] * 0.7141733d));
    xyz[0] = xyz[0] / 0.9642d;
    xyz[1] = xyz[1] / 1d;
    xyz[2] = xyz[2] / 0.8252d;
    
    if (xyz[0] > .008856d)
    {
        xyz[0] = Math.Pow(xyz[0], 0.3333333333333333);
    }
    else
    {
        xyz[0] = (7.787d * xyz[0]) + (16 / 116);
    }
    if (xyz[1] > .008856d)
    {
        xyz[1] = Math.Pow(xyz[1], 0.3333333333333333);
    }
    else
    {
        xyz[1] = (7.787d * xyz[1]) + (16 / 116);
    }
    if (xyz[2] > .008856d)
    {
        xyz[2] = Math.Pow(xyz[2], 0.33333333333333);
    }
    else
    {
        xyz[2] = (7.787d * xyz[2]) + (16 / 116);
    }
    lab[0] = (116 * xyz[1]) - 16;
    lab[1] = 500 * (xyz[0] - xyz[1]);
    lab[2] = 200 * (xyz[1] - xyz[2]);

    searchColourResultl = lab[0];
    searchColourResulta = lab[1];
    searchColourResultb1 = lab[2];
}

为了测试,我使用了 RGB 代码 113,75,41,它给了我

35.699016618103713、13.845077110631209、22.692020016283632

这是不正确的,因为当我将它与 NiX 转换器交叉引用时,它为我提供了相同的 RGB 代码

35.70、13.84、26.81

如果我将其输入 Excel 电子表格,它会给我

35.69902、13.84508、26.81392

excel 和 C# 代码在各个方面都非常相似,但我看不出 C# 代码中的错误出在哪里。

尝试将双精度数更改为浮点数,使情况变得更糟,并将 LAB 中的 B 值发送到 -145

将Y光源从0.8251调整为0.8252,没有区别

2023 年 2 月 12 日

好吧,这变得更奇怪了。我刚刚调整了它(通过将每个部分分成不同的功能并且它起作用了。

void BreakdownRGB()
    {
        r = searchColourr / 255.0d;
        g = searchColourg / 255.0d;
        b = searchColourb / 255.0d;
        if (r > .04045d)
        {
            r = Math.Pow((r + .055d) / 1.055d, 2.4d);
        }
        else
        {
            r = r / 12.92d;
        }
        if (g > .04045d)
        {
            g = Math.Pow((g + .055d) / 1.055d, 2.4d);
        }
        else
        {
            g = g / 12.92d;
        }
        if (b > .04045d)
        {
            b = Math.Pow((b + .055d) / 1.055d, 2.4d);
        }
        else
        {
            b = b / 12.92d;
        }
    }
    
    void RGBtoXYZ()
    {
        //D50 sRGB working space
        x = ((r * 0.4360747d) + (g * 0.3850649d) + (b * 0.1430804d));
        y = ((r * 0.2225045d) + (g * 0.7168786d) + (b * 0.0606169d));
        z = ((r * 0.0139322d) + (g * 0.0971045d) + (b * 0.7141733d));
        x = x / 0.9642d;
        y = y / 1d;
        z = z / 0.8252d;
        if (x > .008856d)
        {
            x = Math.Pow(x, 0.3333333333333333);
        }
        else
        {
            x = (7.787d * x) + (16 / 116);
        }
        if (y > .008856d)
        {
            y = Math.Pow(y, 0.3333333333333333);
        }
        else
        {
            y = (7.787d * y) + (16 / 116);
        }
        if (z > .008856d)
        {
            z = Math.Pow(z, 0.3333333333333333);
        }
        else
        {
            z = (7.787d * z) + (16 / 116);
        }
    }
    
    void XYZtoLAB()
    { 
        l = (116 * y) - 16;
        a = 500 * (x - y);
        b2 = 200 * (y - z);
    
        searchColourResultl = Math.Round(l,5);
        searchColourResulta = Math.Round(a, 5);
        searchColourResultb1 = Math.Round(b2, 5);
    }

但是如果我改成不同的号码(57,37,18),那就很奇怪了

如果我一步步运行,计算xyz[2]时就会出错。在 Excel 中,它给出的结果为 0.201027329,但在 C# (Unity) 中,它给出的结果为 0.06309629423128113,xyz[0] 和 xyz[1] 是正确的。

c# 给出的 RGB 值是

    R = 0.040915196906853191
    G = 0.018500220128379697
    B = 0.0060488330228570539

这在Excel表格上得到确认

如果我改变

    if (z > .008856d)

    if (z < .008856d)

它可以工作,但不适用于其他 RGB 代码

c# colors rgb cielab xyz
1个回答
0
投票

如果您乐意使用库,Unicolour 经过充分测试并给出了预期的结果:

var config = new Configuration(RgbConfiguration.StandardRgb, XyzConfiguration.D50);
var colour = new Unicolour(config, ColourSpace.Rgb255, 113, 75, 41);
Console.WriteLine(colour.Lab); // 35.70 +13.84 +26.81
© www.soinside.com 2019 - 2024. All rights reserved.