简体   繁体   中英

Accessing elements of a cv::Mat with at<float>(i, j). Is it (x,y) or (row,col)?

When we access specific elements of a cv::Mat structure, we can use mat.at(i,j) to access the element at position i,j. What is not immediately clear, however, whether (i,j) refers to the x,y coordinate in the matrix, or the ith row and the jth column.

OpenCV, like many other libraries, treat matrix access in row-major order. That means every access is defined as (row, column) . Note that if you're working with x and y coordinates of an image, this becomes (y, x) , if y is your vertical axis.

Most matrix libraries are the same in that regards, the access is (row, col) as well in, for example, Matlab or Eigen (a C++ matrix library).

Where these applications and libraries do differ however is how the data is actually stored in memory. OpenCV stores the data in row-major order in memory (ie the rows come first), while for example Matlab stores the data in column-major order in memory. But if you're just a user of these libraries, and accessing the data via a (row, col) accessor, you'll never actually see this difference in memory storage order .

So OpenCV handles this a bit strange. OpenCV stores the Mat in row major order, but addressing it over the methood Mat::at() falsely suggests column major order. I think the Opencv documentation is misleading in this case. I had to write this testcase to make sure for myself.

cv::Mat m(3,3,CV_32FC1,0.0f);
m.at<float>(1,0) = 2;
cout << m << endl;

So addressing is done with Mat::at(y,x) :

[0, 0, 0;
2, 0, 0;
0, 0, 0]

But raw pointer access reveals that it is actually stored row major, eg the "2" is in the 4th position. If it were stored in column major order, it would be in the 2nd position.

float* mp = &m.at<float>(0);
for(int i=0;i<9;i++)
    cout << mp[i] << " ";

0 0 0 2 0 0 0 0 0

As a side remark: Matlab stores and addresses a matrix in column major order. It might be annoying, but at least it is consistent.

OpenCV, like may other libraries, treat matrices (and images) in row-major order. That means every access is defined as (row, column) .

Notable exceptions from this general rule are Matlab and Eigen libraries.

根据我在文档中看到的内容,它at(y, x) (即row, col )。

由于cv::Mat实际上是一个通用矩阵,图像只是一种特殊情况,它遵循矩阵索引,因此行( y )位于列( x )之前:

mat.at(i, j) = mat.at(row, col) = mat.at(y, x)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM