2012-07-29 124 views
2

我在很多示例/教程中已经注意到人们使用大括号运算符“()”来进行矩阵访问,这在某些情况下会让我感到困惑。我们假设我们有一个名为M.的矩阵(例如3x4),通过“M(0)”或“M(1)”访问它将返回哪些元素,或大括号内的任何其他奇异参数?我以为你应该指定行和列(如“M(0,1)”或类似的东西)。opencv矩阵大括号运算符

+0

你能指出,使用的一个例子继承? – Mohammad 2012-07-30 05:21:46

+0

'Mat_ X(4,1); (4,1); Mat_ X_(4,1); (...) // A是4x3矩阵,B是4x1矩阵cv :: solve(A,B,X_,DECOMP_SVD); X(0)= X_(0); X(1)= X_(1); X(2)= X_(2); X(3)= 1.0;' – dumpy 2012-07-31 17:12:13

回答

0

这是来自OpenCV的2.4.2

template<typename _Tp> inline _Tp& Mat_<_Tp>::operator()(int i0, int i1) 
{ 
    return ((_Tp*)(data + step.p[0]*i0))[i1]; 
} 
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator()(int i0) 
{ 
    return this->at<_Tp>(i0); 
} 
template<typename _Tp> inline _Tp& Mat_<_Tp>::operator()(int i0, int i1, int i2) 
{ 
    return this->at<_Tp>(i0, i1, i2); 
} 

,这是定义Mat::at(int i0)Mat_公开从Mat

template<typename _Tp> inline const _Tp& Mat::at(int i0) const 
{ 
    if(isContinuous() || size.p[0] == 1) 
     return ((const _Tp*)data)[i0]; 
    if(size.p[1] == 1) 
     return *(const _Tp*)(data + step.p[0]*i0); 
    int i = i0/cols, j = i0 - i*cols; 
    return ((const _Tp*)(data + step.p[0]*i))[j]; 
} 
4

你看到的是线性索引访问 - 即直接以线性方式访问内存。

在一个矩阵中,所有元素都存储在一个大的内存块中,每行都在前一个之后。这就是为什么,如果你想在的位置(i, j)你写somethink喜欢

elem = matrix(j + rowWidth*i) 

访问一个元素,但你可以简单地访问它

elem = matrix(k) 

,当你不关心这是非常有用例如,当您总结矩阵中的所有元素时:

count = width*height; 
sum=0; 
for(i=0;i<count;i++) 
    sum+=matrix(i); 

或者当您有预先计算好的线性指数时。

如果矩阵不会存储在连续的内存块中,例如一个更大矩阵中的感兴趣区域,请注意这种技术可能会产生一些最疯狂的错误。在使用线性索引之前总是检查if (myMat.isContinuous())

+0

如果我有类似“M.at (0)”或“M.at (0)”的内容怎么办? Opencv引用dosumentation指出“at”方法需要一个2d或2个索引(用于行和列)。但是,显然,我发现的代码只使用1个参数并且成功运行。我不明白幕后会发生什么:在这种情况下,哪个矩阵元素正好可以访问? – dumpy 2012-07-31 17:21:36

+0

有两个'at <>'运算符,其中一个可能没有记录,它的工作方式如上所述 – Sam 2012-07-31 17:59:20

+0

如何处理()运算符的参数为cv :: Rect类型? – dinosaur 2016-08-18 21:49:20