Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 颜色配置文件转换-图像不正确_C++_Image Processing_Color Profile_Color Conversion - Fatal编程技术网

C++ 颜色配置文件转换-图像不正确

C++ 颜色配置文件转换-图像不正确,c++,image-processing,color-profile,color-conversion,C++,Image Processing,Color Profile,Color Conversion,我有嵌入ICC配置文件的jpg图像。我已经从文件中提取了ICC配置文件,现在我需要将解压缩后的图像转换为sRGB 我的公式是基于 我使用这个算法: 从RGB->XYZ转换图像 在XYZ上进行颜色调整 转换XYZ->sRGB 对于任务,我有以下代码: Image2d<float> ColorSpace::ConvertRgbToXyz(const Image2d<uint8_t> & input, const IccProfile & inputIc

我有嵌入ICC配置文件的jpg图像。我已经从文件中提取了ICC配置文件,现在我需要将解压缩后的图像转换为sRGB

我的公式是基于

我使用这个算法:

  • 从RGB->XYZ转换图像
  • 在XYZ上进行颜色调整
  • 转换XYZ->sRGB
  • 对于任务,我有以下代码:

    Image2d<float> ColorSpace::ConvertRgbToXyz(const Image2d<uint8_t> & input,
        const IccProfile & inputIcc) {
        size_t len = input.GetPixelsCount();
        std::vector<float> data;
        data.resize(len * 3);
    
        for (size_t i = 0; i < len; i++) {
            const uint8_t * rgb = input.GetPixelStart(i);
            float r = (rgb[0] / 255.0f);
            float g = (rgb[1] / 255.0f);
            float b = (rgb[2] / 255.0f);
    
            r = (r <= 0) ? 0 : pow(r, inputIcc.rGamma);
            g = (g <= 0) ? 0 : pow(g, inputIcc.gGamma);
            b = (b <= 0) ? 0 : pow(b, inputIcc.bGamma);
    
            //sRGB
            float x = inputIcc.rXYZ[0] * r + inputIcc.gXYZ[0] * g + inputIcc.bXYZ[0] * b;
            float y = inputIcc.rXYZ[1] * r + inputIcc.gXYZ[1] * g + inputIcc.bXYZ[1] * b;
            float z = inputIcc.rXYZ[2] * r + inputIcc.gXYZ[2] * g + inputIcc.bXYZ[2] * b;
    
            data[i * 3 + 0] = x;
            data[i * 3 + 1] = y;
            data[i * 3 + 2] = z;
    
        }
    
        return Image2d<float>(input.GetWidth(),
            input.GetHeight(),
            std::move(data),
            PixelFormat::XYZ);
    }
    

    我发现了问题所在

    我使用了错误的参考白色进行色彩调整。我使用的是
    wtpt
    中的值,但应将
    照明体
    用作白色输入


    输出白色仍然设置为D65。

    我发现了问题

    我使用了错误的参考白色进行色彩调整。我使用的是
    wtpt
    中的值,但应将
    照明体
    用作白色输入

    输出白色仍然设置为D65

    void ColorSpace::ChromaticAdaptation(Image2d<float> & input,
        float Xws, float Yws, float Zws,
        float Xwd, float Ywd, float Zwd,
        ChromaticMethod method) {
        size_t len = input.GetPixelsCount();
    
        Matrix3x3 m = Matrix3x3(
            (Xwd / Xws), 0, 0,
            0, (Ywd / Yws), 0,
            0, 0, (Zwd / Zws)
        );
    
        if (method == ChromaticMethod::Bradford) {
            const Matrix3x3 mA = Matrix3x3(
                0.8951000, 0.2664000, -0.1614000,
                -0.7502000, 1.7135000, 0.0367000,
                0.0389000, -0.0685000, 1.0296000
            );
    
            const Matrix3x3 mAInv = Matrix3x3(
                0.9869929, -0.1470543, 0.1599627,
                0.4323053, 0.5183603, 0.0492912,
                -0.0085287, 0.0400428, 0.9684867
            );
    
            float xs = mA.M[0][0] * Xws + mA.M[0][1] * Yws + mA.M[0][2] * Zws;
            float ys = mA.M[1][0] * Xws + mA.M[1][1] * Yws + mA.M[1][2] * Zws;
            float zs = mA.M[2][0] * Xws + mA.M[2][1] * Yws + mA.M[2][2] * Zws;
    
            float xd = mA.M[0][0] * Xwd + mA.M[0][1] * Ywd + mA.M[0][2] * Zwd;
            float yd = mA.M[1][0] * Xwd + mA.M[1][1] * Ywd + mA.M[1][2] * Zwd;
            float zd = mA.M[2][0] * Xwd + mA.M[2][1] * Ywd + mA.M[2][2] * Zwd;
    
            m = Matrix3x3(
                (xd / xs), 0, 0,
                0, (yd / ys), 0,
                0, 0, (zd / zs)
            );
    
            Matrix3x3 res = mAInv;
            res *= m;
            res *= mA;
    
            m = res;
        }
    
    
        for (size_t i = 0; i < len; i++) {
            float * xyz = input.GetPixelStart(i);
            float x = xyz[0];
            float y = xyz[1];
            float z = xyz[2];
    
            float xd = m.M[0][0] * x + m.M[0][1] * y + m.M[0][2] * z;
            float yd = m.M[1][0] * x + m.M[1][1] * y + m.M[1][2] * z;
            float zd = m.M[2][0] * x + m.M[2][1] * y + m.M[2][2] * z;
    
            xyz[0] = xd;
            xyz[1] = yd;
            xyz[2] = zd;
    
        }
    }
    
    Image2d<uint8_t> ColorSpace::ConvertXyzToSRgb_D65(const Image2d<float> & input) {
        size_t len = input.GetPixelsCount();
        std::vector<uint8_t> data;
        data.resize(len * 3);
    
        for (size_t i = 0; i < len; i++) {
            const float * xyz = input.GetPixelStart(i);
            float x = xyz[0];
            float y = xyz[1];
            float z = xyz[2];
    
            //sRGB
            float r =  3.2404542f * x  + -1.5371385f * y + -0.4985314f * z;
            float g = -0.9692660f * x  +  1.8760108f * y +  0.0415560f * z;
            float b =  0.0556434f * x  + -0.2040259f * y +  1.0572252f * z;
    
            //color companding
            //for sRGB
            r = (r > 0.0031308f) ? 1.055f * std::pow(r, 1 / 2.4f) - 0.055f : 12.92f * r;
            g = (g > 0.0031308f) ? 1.055f * std::pow(g, 1 / 2.4f) - 0.055f : 12.92f * g;
            b = (b > 0.0031308f) ? 1.055f * std::pow(b, 1 / 2.4f) - 0.055f : 12.92f * b;
    
            data[i * 3 + 0] = static_cast<uint8_t>(255.0f * std::clamp(r, 0.0f, 1.0f));
            data[i * 3 + 1] = static_cast<uint8_t>(255.0f * std::clamp(g, 0.0f, 1.0f));
            data[i * 3 + 2] = static_cast<uint8_t>(255.0f * std::clamp(b, 0.0f, 1.0f));    
        }
    
        return Image2d<uint8_t>(input.GetWidth(),
            input.GetHeight(),
            std::move(data),
            PixelFormat::RGB);
    }
    
    Header:
      size         = 25908 bytes
      CMM          = 'argl'
      Version      = 2.2.0
      Device Class = Input
      Color Space  = RGB
      Conn. Space  = XYZ
      Date, Time   = 10 Mar 2017, 13:05:37
      Platform     = Microsoft
      Flags        = Not Embedded Profile, Use anywhere
      Dev. Mnfctr. = 0x0
      Dev. Model   = 0x0
      Dev. Attrbts = Reflective, Glossy, Positive, Color
      Rndrng Intnt = Perceptual
      Illuminant   = 0.964203, 1.000000, 0.824905    [Lab 100.000000, 0.000498, -0.000436]
      Creator      = 'argl'
    
    'desc': CoCa 10.3.2017
    'cprt': Copyright_free
    'dmnd': proserv 600i
    'dmdd': Model
    
    'wtpt': 0.768753, 0.822220, 0.665100    [Lab 92.672746, -4.781618, 1.218722]
    'bkpt': 0.003693, 0.004395, 0.003387    [Lab 3.969564, -2.199059, 0.448583]
    
    'rXYZ': 0.956482, 0.326324, 0.010391    [Lab 63.862187, 154.428754, 91.157829]
    'gXYZ': 0.070267, 0.995911, -0.271652    [Lab 99.841662, -290.469249, 685.018939]
    'bXYZ': 0.136230, -0.105103, 1.321716    [Lab -94.938734, 600.671989, -370.133480]
    
    'rTRC': Curve is gamma of 1.234375
    'gTRC': Curve is gamma of 1.296875
    'bTRC': Curve is gamma of 1.312500