当我们访问cv :: Mat结构的特定元素时,我们可以使用mat.at(i,j)来访问位置i,j的元素.然而,不能立即清楚的是,(i,j)是指矩阵中的x,y坐标,还是第i行和第j列.
Ela*_*782 41
与许多其他库一样,OpenCV 以行主顺序处理矩阵访问.这意味着每个访问都被定义为(row, column).请注意,如果您正在使用图像的x和y坐标(y, x),那么这将成为y您的垂直轴.
大多数矩阵库在这方面都是相同的,访问(row, col)也在例如Matlab或Eigen(C++矩阵库)中.
然而,这些应用程序和库的不同之处在于数据实际存储在内存中的方式.OpenCV以行主要顺序将数据存储在内存中(即行首先出现),而例如Matlab将数据按列主要顺序存储在内存中.但是,如果您只是这些库的用户,并通过访问器访问数据(row, col),您将永远不会真正看到内存存储顺序的这种差异.
小智 26
所以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;
Run Code Online (Sandbox Code Playgroud)
所以使用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] << " ";
Run Code Online (Sandbox Code Playgroud)
0 0 0 2 0 0 0 0 0
作为旁注:Matlab以列主要顺序存储和寻址矩阵.这可能很烦人,但至少它是一致的.
Sam*_*Sam 20
与其他库一样,OpenCV可以按行主顺序处理矩阵(和图像).这意味着每个访问都被定义为(row, column).
这个一般规则的显着例外是Matlab和Eigen库.
由于cv::Mat实际上是一般矩阵,图像只是一种特殊情况,它遵循矩阵索引,因此row(y)位于column(x)之前:
mat.at(i, j) = mat.at(row, col) = mat.at(y, x)
Run Code Online (Sandbox Code Playgroud)