OpenCV Tiff 错误的颜色值读数

Posted

技术标签:

【中文标题】OpenCV Tiff 错误的颜色值读数【英文标题】:OpenCV Tiff Wrong Color Values Readout 【发布时间】:2021-10-14 16:23:10 【问题描述】:

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

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

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

这是读取OpenCV中像素值的代码的sn-p

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 StudioAdobeRGB:

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

PS1:我也尝试将 GIMP/CaptureOne 中的输出色彩空间更改为 sRGB,但差异仍然几乎相同,而不是更接近 OpenCV

PS2:在从图像COLOR_RGB2BGR 提取 RGB 值之前,我正在反转 OpenCV imread 通道的顺序。

【问题讨论】:

您说您有一个 TIF,但共享了一个 PNG?请分享您的实际 TIF,可能使用 Dropbox 或 Google Drive。你说你的图像是 16 位的,但你的白色显示为 8 位的 255,而你的 OpenCV 值是浮点数,通常是 32 位而不是 16 位? 已将链接添加到源图像(tiff 16 位)。是的,这就是软件输出如何将 16 位转换为 8 位范围 [0-255] 的方式。对于我的OpenCV 输出,有一个conv16_8 因子,使用该因子将值转换为8 位范围[0-255]。如有必要,我可以提供实际的 16 位读数,但我认为这不是问题 您分享的 TIFF 文件是 24 位的,即 RGB888。 哦,对不起...我似乎弄错了图像。请现在再次检查链接我已经更新了它 好的,您现在共享的图像是每通道 16 位,所以实际上每像素 48 位 - 不错的相机和镜头???? 【参考方案1】:

OP 说:

我有一个 16 位 tiff 图像没有颜色配置文件(嵌入了相机配置文件)

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

据我所知,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

【讨论】:

【参考方案2】:

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

【讨论】:

以上是关于OpenCV Tiff 错误的颜色值读数的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 访问像素的颜色值

通过强度值标准化颜色通道和图像,OpenCV

根据OpenCV中一个通道中的值查找最大颜色像素

OpenCV:如何为每个像素填充具有每种 RGB 颜色值的 rgb 图像?

OpenCV这么简单为啥不学——1.9cvtColor颜色空间转换(全色值效果演示)

python-opencv-图像颜色映射