繁体   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)?

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

与许多其他库一样,OpenCV以行主顺序处理矩阵访问 这意味着每个访问都定义为(row, column) 请注意,如果您正在处理图像的x和y坐标,则如果y是垂直轴,则变为(y, x)

大多数矩阵库在这方面是相同的,访问是(row, col)以及例如Matlab或Eigen(C ++矩阵库)。

然而,这些应用程序和库的不同之处在于数据实际存储在内存中的方式。 OpenCV以行 - 主要顺序将数据存储在内存中(即行首先出现),而例如Matlab将数据按列主要顺序存储在内存中。 但是如果你只是这些库的用户,并通过(row, col)访问器访问数据,你将永远不会真正看到内存存储顺序的这种差异。

所以OpenCV处理这个有点奇怪。 OpenCV按行主要顺序存储Mat,但是通过matood Mat :: at()对它进行处理会错误地建议列主要顺序。 我认为Opencv文档在这种情况下具有误导性。 我不得不写这个测试用例来确保自己。

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

所以使用Mat :: at(y,x)完成寻址:

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

但是原始指针访问显示它实际上存储了行主要,例如“2”处于第4位。 如果它以列主要顺序存储,则它将处于第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

作为旁注:Matlab以列主要顺序存储和寻址矩阵。 这可能很烦人,但至少它是一致的。

与其他库一样,OpenCV可以按行主顺序处理矩阵(和图像)。 这意味着每个访问都定义为(row, column)

这个一般规则的显着例外是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