hekimgil hekimgil - 10 months ago 78
C++ Question

How to use the correct type name when using OpenCV cv::Mat.at function

It will probably be much easier to describe the situation than describing the problem. I use the following two lines of code in C++ using OpenCV:

std::cout << "value near i,j: " << myMat(Rect(i,j,2,2)) << std::endl;
std::cout << "value at i,j: " << myMat.at<double>(i,j) << std::endl;

And I get the following results:

value near i,j: [34, 42;
39, 44]
value at i,j: 24

I believe the first number in the first value (24) and the value in the second line (34) should be equal. The datatype in myMat should currently be defined as CV_64F. My conclusion is that I am doing something wrong when converting from the OpenCV datatypes to C++ primitive types because I had much worse values when I used CV_16S initially. So what sort of correction do I need to do to access the value in the cv::Mat construction correctly?

P.S: myMat is created and assigned as follows:

Mat yourMat, myMat;
[... yourMat is assigned ...]
Sobel(yourMat, myMat, CV_64F, 1, 0, 3, 1, 0, BORDER_DEFAULT);

P.S.2: I found a similar question here but the answer there seems to be only a work-around in assigning.

Answer Source

You should switch i,j in second line: myMat.at<double>(j,i)

In myMat(Rect(i,j,2,2)) you're using the Rect constructor:

x, y, width, height

so the top left of your Rect is in (x,y) = (i, j). However when you access a value with .at you access it with .at<Tp>(row, col), which is the inverse of (x,y), since row = y and col = x.

So you're effectively reading the value at position (y, x) = (j, i).