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