OpenCV Tiff 错误的颜色值读数

OpenCV Tiff Wrong Color Values Readout

我有一张 16-bit tiff 图像,没有颜色配置文件(嵌入相机配置文件),我试图在 OpenCV 中读取它的 RGB 值。但是,将输出值与通过 GIMP 打开图像时给出的值进行比较,例如给出完全不同的值(GIMP 在保持图像的配置文件选项的情况下打开;没有配置文件转换)。我也尝试过另一个图像工作室软件,如 CaptureOne,结果符合 GIMP 不同于 OpenCV 输出。

不确定在 OpenCV 中读取和打开图像是否有问题,尽管使用了 IMREAD_UNCHANGED 标志。

我也尝试使用 FreeImage 库读取图像,但结果仍然相同。

这是读取 OpenCV

中像素值的代码片段
const float Conv16_8 = 255.f / 65535.f;
cv::Vec3d curVal;
// upperLeft/lowerRight are just some pre-defined corners for the ROI
for (int row = upperLeft.y; row <= lowerRight.y; row++) {
    unsigned char* dataUCPtr = img.data + row * img.step[0];
    unsigned short* dataUSPtr = (unsigned short*)dataUCPtr;

    dataUCPtr += 3 * upperLeft.x;
    dataUSPtr += 3 * upperLeft.x;

    for (int col = upperLeft.x; col <= lowerRight.x; col++) {
        if (/* some check if the pixel is valid */) {
            if (img.depth() == CV_8U) {
                for (int chan = 0; chan < 3; chan++) {
                    curVal[chan] = *dataUCPtr++;
                }

            }
            else if (img.depth() == CV_16U) {
                for (int chan = 0; chan < 3; chan++) {
                    curVal[chan] = (*dataUSPtr++)*Conv16_8;
                }
            }
            avgX += curVal;
        }
        else {
            dataUCPtr += 3;
            dataUSPtr += 3;
        }
    }
}

这是我正在阅读的图像 (download the image),它的 RGB 读数在

CaptureOne Studio Adob​​eRGB:

vs OpenCV RGB(A1=白色 --> F1=黑色):

PS1:我也尝试将 GIMP/CaptureOne 中的输出颜色 space 更改为 sRGB,但差异仍然几乎相同,没有更接近 OpenCV

PS2:在从图像 COLOR_RGB2BGR

中提取 RGB 值之前,我正在反转 OpenCV imread 通道的顺序

事实证明,这就是在 cv::Mat 数据上拥有、加载和应用正确的 ICC 配置文件。为此,必须在 OpenCV 旁边使用颜色管理引擎,例如 LittleCMS.

OP 说:

I have a 16-bit tiff image with no color profile (camera profile embedded)

嗯,不,您的图像肯定 具有 颜色配置文件,不应忽略它。嵌入的配置文件与每个像素的数值一样重要。没有定义的配置文件,像素值有点没有意义。

据我所知,默认情况下 OpenCV 不会线性化 gamma...除非它会...无论如何,配置文件中指示的 gamma 是唯一的:

现在将其与 sRGB 进行比较:

因此无法使用 sRGB 转换。

如果您正在寻找性能,通过 LUT 应用曲线通常比全面的色彩管理系统更有效。

在这种情况下,使用 LUT。以下 LUT 取自颜色配置文件、16 位值和 256 步:

    // Phase One TRC from color profile

  profileTRC = [0x0000,0x032A,0x0653,0x097A,0x0CA0,0x0FC2,0x12DF,0x15F8,0x190C,0x1C19,0x1F1E,0x221C,0x2510,0x27FB,0x2ADB,0x2DB0,0x3079,0x3334,0x35E2,0x3882,0x3B11,0x3D91,0x4000,0x425D,0x44A8,0x46E3,0x490C,0x4B26,0x4D2F,0x4F29,0x5113,0x52EF,0x54BC,0x567B,0x582D,0x59D1,0x5B68,0x5CF3,0x5E71,0x5FE3,0x614A,0x62A6,0x63F7,0x653E,0x667B,0x67AE,0x68D8,0x69F9,0x6B12,0x6C23,0x6D2C,0x6E2D,0x6F28,0x701C,0x710A,0x71F2,0x72D4,0x73B2,0x748B,0x755F,0x762F,0x76FC,0x77C6,0x788D,0x7951,0x7A13,0x7AD4,0x7B93,0x7C51,0x7D0F,0x7DCC,0x7E8A,0x7F48,0x8007,0x80C8,0x8189,0x824C,0x8310,0x83D5,0x849B,0x8562,0x862B,0x86F4,0x87BF,0x888A,0x8956,0x8A23,0x8AF2,0x8BC0,0x8C90,0x8D61,0x8E32,0x8F04,0x8FD7,0x90AA,0x917E,0x9252,0x9328,0x93FD,0x94D3,0x95AA,0x9681,0x9758,0x9830,0x9908,0x99E1,0x9ABA,0x9B93,0x9C6C,0x9D45,0x9E1F,0x9EF9,0x9FD3,0xA0AD,0xA187,0xA260,0xA33A,0xA414,0xA4EE,0xA5C8,0xA6A1,0xA77B,0xA854,0xA92D,0xAA05,0xAADD,0xABB5,0xAC8D,0xAD64,0xAE3B,0xAF11,0xAFE7,0xB0BC,0xB191,0xB265,0xB339,0xB40C,0xB4DE,0xB5B0,0xB680,0xB750,0xB820,0xB8EE,0xB9BC,0xBA88,0xBB54,0xBC1F,0xBCE9,0xBDB1,0xBE79,0xBF40,0xC005,0xC0CA,0xC18D,0xC24F,0xC310,0xC3D0,0xC48F,0xC54D,0xC609,0xC6C5,0xC780,0xC839,0xC8F2,0xC9A9,0xCA60,0xCB16,0xCBCA,0xCC7E,0xCD31,0xCDE2,0xCE93,0xCF43,0xCFF2,0xD0A0,0xD14D,0xD1FA,0xD2A5,0xD350,0xD3FA,0xD4A3,0xD54B,0xD5F2,0xD699,0xD73E,0xD7E3,0xD887,0xD92B,0xD9CE,0xDA6F,0xDB11,0xDBB1,0xDC51,0xDCF0,0xDD8F,0xDE2C,0xDEC9,0xDF66,0xE002,0xE09D,0xE138,0xE1D2,0xE26B,0xE304,0xE39C,0xE434,0xE4CB,0xE562,0xE5F8,0xE68D,0xE722,0xE7B7,0xE84B,0xE8DF,0xE972,0xEA04,0xEA97,0xEB29,0xEBBA,0xEC4B,0xECDC,0xED6C,0xEDFC,0xEE8B,0xEF1A,0xEFA9,0xF038,0xF0C6,0xF154,0xF1E1,0xF26F,0xF2FC,0xF388,0xF415,0xF4A1,0xF52D,0xF5B9,0xF645,0xF6D0,0xF75B,0xF7E6,0xF871,0xF8FC,0xF987,0xFA11,0xFA9B,0xFB26,0xFBB0,0xFC3A,0xFCC4,0xFD4E,0xFDD7,0xFE61,0xFEEB,0xFF75,0xFFFF]

如果需要线性化值的匹配数组,它将是

   [0x0000,0x0101,0x0202,0x0303,0x0404....

但大多数用途不需要这样的数组,因为 PhaseOne TRC 数组的索引值直接与线性值相关。

phaseOneTRC[0x80]0xAD64
线性值为 0x80 * 0x101.