2012-07-29 121 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