Search code examples
copencvrgbcolor-spaceimread

OpenCV Tiff Wrong Color Values Readout


I have a 16-bit tiff image with no color profile (camera profile embedded) and I am trying to read its RGB values in OpenCV. However, comparing the output values to the values given when the image is opened by GIMP for example gives totally different values (GIMP being opened with keeping the image's profile option; no profile conversion). I have tried also another image studio software like CaptureOne and the result accords with GIMP differs from OpenCV output.

Not sure if reading and opening the image in OpenCV is wrong somehow, in spite of using IMREAD_UNCHANGED flag.

I have as well tried to read the image using FreeImage library but still the same result.

Here is a snippet of the code reading pixels' values in 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;
        }
    }
}

and here is the image (download the image) I am reading with its RGB readouts in

CaptureOne Studio AdobeRGB:

CaptureOne AdobeRGB Readouts

vs OpenCV RGB (A1=white --> F1=Black):

OpenCV RGB

PS1: I have tried also to change the output color space in GIMP/CaptureOne to sRGB but still the difference is almost the same, not any closer to OpenCV

PS2: I am reversing OpenCV imread channels' order before extracting the RGB values from the image COLOR_RGB2BGR


Solution

  • It turned out, it is all about having, loading and applying the proper ICC profile on the cv::Mat data. To do that one must use a color management engine along side OpenCV such as LittleCMS.