0

I'm new to OpenCV and I stuck with the problem while declaring a Mat instance.

#include <opencv2\opencv.hpp>
int main(int argc, char *argv[]) {

    cv::Mat before = cv::imread("./irene.jpg", CV_LOAD_IMAGE_COLOR);

    cv::imshow("before", before);
    cv::waitKey(0);

    cv::Mat after(cv::Size(before.rows, before.cols), CV_8UC3);

    for (int y = 0; y < before.rows; y++) {
        for (int x = 0; x < before.cols; x++) {
            after.at<cv::Vec3b>(y, x)[0] = before.at<cv::Vec3b>(y, x)[2];
            after.at<cv::Vec3b>(y, x)[1] = before.at<cv::Vec3b>(y, x)[1];
            after.at<cv::Vec3b>(y, x)[2] = before.at<cv::Vec3b>(y, x)[0];
        }
    }

    cv::imshow("after", after);
    cv::waitKey(0);
    return 0;
}

Just a simple code for changing color of an image. The problem is that, when I try to use cv::Size(), the compiler returns Assertion Failure. It builds okay, but when I try to press any key to go next of the code, it makes an exception.

What the compiler references and put on the console is:

OpenCV(3.4.3) Error: Assertion failed ((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels())) in cv::Mat::at, file c:\opencv343\opencv\build\include\opencv2\core\mat.inl.hpp, line 1101

I'm certain on that the exception is thrown because of the Size() struct, because if I change Size(before.rows, before.cols) to before.rows, before.cols, it works fine!

I cannot figure out what is wrong, but all the tutorials say the code I tried is okay code.

cadenzah
  • 928
  • 3
  • 10
  • 23
  • 1
    Read the documentation of [cv::Size](https://docs.opencv.org/3.4.3/d6/d50/classcv_1_1Size__.html). Doing so, you should notice that the first parameter of the constructor is **width**, but you're setting it to number of rows (i.e. height). | As with so many other questions here... documentation is your friend. Get familiar with it, and use it. – Dan Mašek Nov 19 '18 at 14:27
  • Also, it seems like all you're trying to do here is to swap channels 0 and 2. This is basically equivalent to a conversion between BGR and RGB. Hence, a simple `cv::cvtColor(after, before, cv::COLOR_BGR2RGB)` will do the same job as your two nested loops, and most likely much faster too. – Dan Mašek Nov 19 '18 at 14:31
  • You are right. the code switched them each other. Maybe it was not wrong because in many tutorials they were identical values (square matrix). – cadenzah Nov 19 '18 at 14:31

1 Answers1

0

This exception occurred because I set the width and height inside the Size() in wrong order. Right order is cv::Size(width(cols)_of_image, height(rows)_of_image)

It was not a problem for many tutorials as they usually used image of square size.

cadenzah
  • 928
  • 3
  • 10
  • 23