C++ 使用 at<float>(i, j) 访问 cv::Mat 的元素。是 (x,y) 还是 (row,col)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8184053/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing elements of a cv::Mat with at<float>(i, j). Is it (x,y) or (row,col)?
提问by Chris
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.
当我们访问 cv::Mat 结构的特定元素时,我们可以使用 mat.at(i,j) 访问位置 i,j 的元素。然而,目前尚不清楚 (i,j) 是指矩阵中的 x,y 坐标,还是第 i 行和第 j 列。
采纳答案by Sam
OpenCV, like may other libraries, treat matrices (and images) in row-major order. That means every access is defined as (row, column)
.
OpenCV 与其他库一样,按行优先顺序处理矩阵(和图像)。这意味着每个访问都被定义为(row, column)
.
Notable exceptions from this general rule are Matlab and Eigen libraries.
这条一般规则的显着例外是 Matlab 和 Eigen 库。
回答by Ela782
OpenCV, like many other libraries, treat matrix accessin 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.
与许多其他库一样,OpenCV以行优先顺序处理矩阵访问。这意味着每个访问都被定义为(row, column)
. 请注意,如果您正在处理图像的 x 和 y 坐标,则这将变为(y, x)
, ify
是您的垂直轴。
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 storedin memory. OpenCV stores the data in row-major order in memory (i.e. 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.
然而,这些应用程序和库的不同之处在于数据在内存中的实际存储方式。OpenCV 以行优先顺序将数据存储在内存中(即行在前),而例如 Matlab 以列优先顺序将数据存储在内存中。但是,如果您只是这些库的用户,并通过访问器访问数据(row, col)
,您将永远不会真正看到内存存储顺序的这种差异。
回答by Insa
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.
所以 OpenCV 处理这个有点奇怪。OpenCV 以行主要顺序存储 Mat,但通过 Mat::at() 解决它错误地建议列主要顺序。我认为 Opencv 文档在这种情况下具有误导性。我不得不写这个测试用例来确保自己。
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;
2, 0, 0;
0, 0, 0]
[0, 0, 0;
2, 0, 0;
0, 0, 0]
But raw pointer access reveals that it is actually stored row major, e.g. the "2" is in the 4th position. If it were stored in column major order, it would be in the 2nd position.
但是原始指针访问显示它实际上是存储在行主要的,例如“2”在第 4 个位置。如果它以列主要顺序存储,它将位于第二个位置。
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. It might be annoying, but at least it is consistent.
作为旁注:Matlab 按列主要顺序存储和寻址矩阵。这可能很烦人,但至少它是一致的。
回答by Etienne de Martel
From what I've read in the documentation, it's at(y, x)
(i.e. row, col
).
从我在文档中读到的,它是at(y, x)
(即row, col
)。
回答by Christian Rau
Since cv::Mat
is actually a general matrix, with images being just a special case, it follows matrix indexing and therefore the row (y
) comes before the column (x
):
由于cv::Mat
实际上是一个通用矩阵,图像只是一个特例,它遵循矩阵索引,因此行 ( y
) 在列 ( x
)之前:
mat.at(i, j) = mat.at(row, col) = mat.at(y, x)