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

时间:2011-11-18 14:34:30

标签: c++ opencv

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

5 个答案:

答案 0 :(得分:36)

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

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

这些应用程序和库确实存在差异,但数据实际上是如何存储在内存中。 OpenCV以行 - 主要顺序将数据存储在存储器中(即,行首先出现),而例如Matlab将数据按列主要顺序存储在存储器中。但是,如果您只是这些库的用户,并通过(row, col)访问者访问数据,那么您将永远不会在内存存储顺序中看到这种差异。

答案 1 :(得分:25)

所以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以列主要顺序存储和寻址矩阵。这可能很烦人,但至少它是一致的。

答案 2 :(得分:18)

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

这个一般规则的显着例外是Matlab和Eigen库。

答案 3 :(得分:12)

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

答案 4 :(得分:8)

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

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