0

cv::Mat::Mat ( Size size, int type )

Parameters size 2D array size: Size(cols, rows) . In the Size() constructor, the number of rows and the number of columns go in the reverse order.

docs

I am reading a 4000x3000 image (verified via gimp), gdb reports a 4000x3000 frame. But when I create a cv::Mat{ cv::Size{ 4000, 3000 } };, the result is f.rows == 4000; f.cols == 3000;.

What's the advantage of designing the interface thus?

Vorac
  • 8,726
  • 11
  • 58
  • 101
  • https://stackoverflow.com/questions/25642532/opencv-pointx-y-represent-column-row-or-row-column/25644503#25644503 – Micka Feb 24 '19 at 11:55

3 Answers3

1

I guess this is more a question, why cols are before rows for the cv::Size contructor, while a cv::Mat constructor expects rows, then cols?

So this is one of those question, (y, x) or (x, y). From a memory point the calculation works like x+y*width, so x should be first.

mathematicans on the other hand used to use (y, x) for centuries wiki reference.

Cubimon
  • 150
  • 3
  • 11
0

Hm, cv::Mat{ cv::Size{ 4000, 3000 } }; works? I doubt.

Try this ways:

cv::Mat img1(cv::Size(4000, 3000), CV_8UC3);
cv::Mat img2(3000, 4000, CV_8UC3);

They are really works.

Nuzhny
  • 1,869
  • 1
  • 7
  • 13
0

cv::Mat is view as a matrix and it is accessed/created in the order you will do with a matrix, for example:

int rows = 4000, cols = 3000, type = CV_8U;
cv::Mat something( rows, cols, type, cv::Scalar::all(0));
something.at<uchar>(178 /*row*/, 928/*col*/) = 124;

In OpenCV there is more than cv::Mat, for instance cv::Point, which uses cartesian coordinates, i.e. x,y. In matrix notation speaking, the points are (col, row). And guess what, it can be also used with .at to specify a point, like this:

something.at<uchar>(cv::Point(928/*col*/,178/*row*/)) = 124;

We also have cv::Rect, which is constructed with the top left point and bottom right point or with the top left point and the width and the height. In code it is something like:

cv::Rect r(10, 12, 100, 120);
// or in other words
cv::Rect r2(cv::Point(10,12), cv::Size(100, 120));

This cv::Size notation (width, height) is consistent with several other programs/os (like windows) where you can see the size specified as width x height (in your example 4000 x 3000).

Having said all this, you can see that OpenCV made itself quite flexible in the notations that can be used. Some people will stick with the matrix notations for cv::Mat and cartesian coordinates for Points and Rects, some other people prefer everything in cartesian... Why this decision? you better ask the creators of OpenCV, but I can tell you several other libraries does the same (see an image as a matrix and use matrix notation for it).

I hope this clears your doubts, but if not just leave a comment

api55
  • 11,070
  • 4
  • 41
  • 57