Алгоритм преобразования цветового пространства LAB в XYZ и XYZ в RGB

Я попытался преобразовать цветовое пространство CIE-LAB в цветовое пространство RGB. Но тут ошибка.

  • входные значения LAB = (46,41,-39,24,33,51)
  • полученный результат Значения XYZ =(-2,641482,15,57358,-5,368798)
  • получил результат RGB vaues = (-791,4557,135,8615,-271,5485)

Значения XYZ должны быть (9,22,15,58,5,54) Значения RGB должны быть (50,125,50)

Я проверил эти значения на http://colorizer.org/

Где я ошибся?

Если вы проверите следующий код и ответите мне. Я буду рад. Спасибо.

Я конвертирую RGB в XYZ и XYZ в преобразование цветового пространства LAB. Вы можете проверить это по следующей ссылке.

Алгоритм преобразования цветового пространства RGB / XYZ и XYZ-LAB

public static Vector4 LabToXYZ(Vector4 color)
        {
            float[] xyz = new float[3];
            float[] col = new float[] { color[0], color[1], color[2], color[3]};


            xyz[1] = (col[0] + 16.0f) / 116.0f;
            xyz[0] = (col[1] / 500.0f) + xyz[0];
            xyz[2] = xyz[0] - (col[2] / 200.0f);

            for (int i = 0; i < 3; i++)
            {
                float pow = xyz[i] * xyz[i] * xyz[i];
                if (pow > .008856f)
                {
                    xyz[i] = pow;
                }
                else
                {
                    xyz[i] = (xyz[i]- 16.0f / 116.0f) / 7.787f;
                }
            }

            xyz[0] = xyz[0] * (95.047f);
            xyz[1] = xyz[1] * (100.0f);
            xyz[2] = xyz[2] * (108.883f);

            return new Vector4(xyz[0], xyz[1], xyz[2], color[3]);
        }

public static Vector4 XYZToRGB(Vector4 color)
        {
            float[] rgb = new float[3];
            float[] xyz = new float[3];
            float[] col = new float[] { color[0], color[1], color[2] };



            for (int i = 0; i < 3; i++)
            {
                xyz[i] = col[i] / 100.0f;
            }

            rgb[0] = (xyz[0] * 3.240479f) + (xyz[1] * -1.537150f) + (xyz[2] * -.498535f);
            rgb[1] = (xyz[0] * -.969256f) + (xyz[1] *  1.875992f) + (xyz[2] * .041556f);
            rgb[2] = (xyz[0] * .055648f) +  (xyz[1] * -.204043f) + (xyz[2] * 1.057311f);

            for (int i = 0; i < 3; i++)
            {
                if (rgb[i] > .0031308f)
                {
                    rgb[i] = (1.055f * (float)Math.Pow(rgb[i], (1.0f / 2.4f))) - .055f;
                }
                else
                {
                    rgb[i] = rgb[i] * 12.92f;
                }
            }

            rgb[0] = rgb[0] * 255.0f;
            rgb[1] = rgb[1] * 255.0f;
            rgb[2] = rgb[2] * 255.0f;



            return new Vector4(rgb[0], rgb[1], rgb[2], color[3]);
        }

public static Vector4 LabToRGB(Vector4 color)
        {
            Vector4 xyz = LabToXYZ(color);
            Vector4 rgb = XYZToRGB(xyz);

            Debug.Log("R: " + rgb[0]);
            Debug.Log("G: " + rgb[1]);
            Debug.Log("B: " + rgb[2]);
            Debug.Log("A: " + color[3]);

            return new Vector4 (rgb[0],rgb[1],rgb[2]);
        }

1 ответ

Я изменил только вычисления XYZ в функции LabToXYZ и получил правильные значения. Есть небольшая ошибка.

xyz[1] = (col[0] + 16.0f) / 116.0f;
xyz[0] = (col[1] / 500.0f) + xyz[0];
xyz[2] = xyz[0] - (col[2] / 200.0f);

Не является правильным. Это должно быть так, как показано ниже

xyz[1] = (col[0] + 16.0f) / 116.0f;
xyz[0] = (col[1] / 500.0f) + xyz[1];
xyz[2] = xyz[1] - (col[2] / 200.0f);

Кроме того, вы можете переключиться на функцию LabToXYZ, как показано ниже.

public static Vector4 LabToXYZ(Vector4 color)
        {
            float[] xyz = new float[3];
            float[] col = new float[] { color[0], color[1], color[2], color[3]};

            xyz[1] = (col[0] + 16.0f) / 116.0f;
            xyz[0] = (col[1] / 500.0f) + xyz[1];
            xyz[2] = xyz[1] - (col[2] / 200.0f);

             for (int i = 0; i < 3; i++)
            {
                float pow = xyz[i] * xyz[i] * xyz[i];
                float ratio = (6.0f / 29.0f);
                if (xyz[i] > ratio)
                {
                    xyz[i] = pow;
                }
                else
                {
                    xyz[i] = (3.0f * (6.0f / 29.0f) * (6.0f / 29.0f) * (xyz[i] - (4.0f / 29.0f)));
                }
            }
            xyz[0] = xyz[0] * 95.047f;
            xyz[1] = xyz[1] * 100.0f;
            xyz[2] = xyz[2] * 108.883f;

            return new Vector4(xyz[0], xyz[1], xyz[2], color[3]);
        }

см. https://en.wikipedia.org/wiki/CIELAB_color_space для других вычислений

Другие вопросы по тегам