c++opencvopencv3.0opencv3.1opencv-mat

Confused by OpenCV image representation


I'm loading image into cv::Mat. For some reason, when I'm printing each pixel data, color doesn't match with actual image pixels. Clearly, there is no (28, 36, 255), (127, 127, 255) colors on the image. Could someone point to my mistake? Here are code and test image.

cv::Mat img = imread("image.png", CV_LOAD_IMAGE_COLOR);
auto *input = (unsigned char*)(img.data);
int r, g, b;
for (int i = 0; i < img.rows; i++) {
    for (int j = 0; j < img.cols; j++) {
        b = input[img.step * j + i];
        g = input[img.step * j + i + 1];
        r = input[img.step * j + i + 2];
        std::cout << r << " " << g << " " << b << std::endl;
    }
}

enter image description here


Solution

  • Your current calculation,

    b = input[img.step * j + i];
    

    gives you the width of each row times the column you're on, plus the current row number. Multiplying the width of something by where you are on that width doesn't give you anything meaningful.

    What you really want is the width of the row times the row number you're on. That gives you the offset of the first byte of that row. Then you need to add the offset to the first byte of the BGR triplet in that row, which is 3 (the number of channels) times the column you're on. From there you can get the offsets for the BGR values:

    b = input[img.step * i + img.channels() * j];
    

    Using this method, the value of the first red pixel in your image is:

    237 28 36