简体   繁体   English

使用at访问cv :: Mat的元素 <float> (i,j)。 是(x,y)还是(row,col)?

[英]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. 当我们访问cv :: Mat结构的特定元素时,我们可以使用mat.at(i,j)来访问位置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. 然而,不能立即清楚的是,(i,j)是指矩阵中的x,y坐标,还是第i行和第j列。

OpenCV, like many other libraries, treat matrix access in row-major order. 与许多其他库一样,OpenCV以行主顺序处理矩阵访问 That means every access is defined as (row, column) . 这意味着每个访问都定义为(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. 请注意,如果您正在处理图像的x和y坐标,则如果y是垂直轴,则变为(y, x)

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). 大多数矩阵库在这方面是相同的,访问是(row, col)以及例如Matlab或Eigen(C ++矩阵库)。

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. OpenCV以行 - 主要顺序将数据存储在内存中(即行首先出现),而例如Matlab将数据按列主要顺序存储在内存中。 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 . 但是如果你只是这些库的用户,并通过(row, col)访问器访问数据,你将永远不会真正看到内存存储顺序的这种差异。

So OpenCV handles this a bit strange. 所以OpenCV处理这个有点奇怪。 OpenCV stores the Mat in row major order, but addressing it over the methood Mat::at() falsely suggests column major order. OpenCV按行主要顺序存储Mat,但是通过matood Mat :: at()对它进行处理会错误地建议列主要顺序。 I think the Opencv documentation is misleading in this case. 我认为Opencv文档在这种情况下具有误导性。 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) : 所以使用Mat :: at(y,x)完成寻址:

[0, 0, 0; [0,0,0;
2, 0, 0; 2,0,0;
0, 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. 但是原始指针访问显示它实际上存储了行主要,例如“2”处于第4位。 If it were stored in column major order, it would be in the 2nd position. 如果它以列主要顺序存储,则它将处于第2位。

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 0 0 0 2 0 0 0 0 0

As a side remark: Matlab stores and addresses a matrix in column major order. 作为旁注:Matlab以列主要顺序存储和寻址矩阵。 It might be annoying, but at least it is consistent. 这可能很烦人,但至少它是一致的。

OpenCV, like may other libraries, treat matrices (and images) in row-major order. 与其他库一样,OpenCV可以按行主顺序处理矩阵(和图像)。 That means every access is defined as (row, column) . 这意味着每个访问都定义为(row, column)

Notable exceptions from this general rule are Matlab and Eigen libraries. 这个一般规则的显着例外是Matlab和Eigen库。

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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