2014-09-23 129 views
1

Mat a =(Mat_(3,3)< < 1,0,0,0,1,0,0,0,1);
cv :: Mat b = a.row(1);如果a是一個cv :: Mat和cv :: Mat b = a.row(1),那麼這兩個cv :: Mat實例有什麼區別?

cv::Mat有一個稱爲data場,也就是其被指向爲墊的實際存儲器的指針。
我知道這是淺拷貝,沒有新的內存將被分配來存儲a.row(1)b的元素。
ab將共享相同的內存。
data字段的b將與adata字段相同。

我的問題是:
如果bdata場相同adata場,又是什麼ab之間的區別?
他們的data字段是相同的,但其他功能知道ab是不同的!
他們如何知道這一點?

+0

在這種情況下M是什麼?你忘了幾行以使其可以理解,但我想我知道這是怎麼回事..編輯 – 2014-09-23 08:57:31

+0

..你能告訴我在兩個cv :: Mat裏面發生了什麼嗎? – alexyangfox 2014-09-23 09:01:03

+0

對不起,有些錯別字......現在,修正了..你能幫我解決這個問題嗎? – alexyangfox 2014-09-23 09:08:53

回答

1

我的假設錯了!
雖然沒有分配新內存,但abdata字段不同!

這裏的頭在mat.hpp一個代碼段,其中cv::Mat的定義是這樣的:

class CV_EXPORTS Mat 
{ 
public: 
    // ... a lot of methods ... 
    ... 

     /*! includes several bit-fields: 
     - the magic signature 
     - continuity flag 
     - depth 
     - number of channels 
     */ 
     int flags; 
    //! the array dimensionality, >= 2 
    int dims; 
    //! the number of rows and columns or (-1, -1) when the array has more than 2 dimensions 
    int rows, cols; 
    uchar* data; 

    //! pointer to the reference counter; 
    // when array points to user-allocated data, the pointer is NULL 
    int* refcount; 

    // other members 
    ... 
}; 

當你正在做淺複製,只有指針,data(不data指着東西)會複製。
沒有新的內存將被分配。
說,我們有一個cv::Mata

cv :: Mat b = a;

bdata字段將是相同a的。 沒有新的內存將分配給b

但對於以下代碼:

CV ::板坯B = a.col(1);

這裏是matrix.cpp一個代碼段,其中包括CV ::墊函數的實現:

Mat::Mat(const Mat& m, const Range* ranges) 
    : flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0), 
     datalimit(0), allocator(0), u(0), size(&rows) 
{ 
int i, d = m.dims; 

CV_Assert(ranges); 
for(i = 0; i < d; i++) 
{ 
    Range r = ranges[i]; 
    CV_Assert(r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i])); 
} 
*this = m; 
for(i = 0; i < d; i++) 
{ 
    Range r = ranges[i]; 
    if(r != Range::all() && r != Range(0, size.p[i])) 
    { 
     size.p[i] = r.end - r.start; 
     data += r.start*step.p[i]; 
     flags |= SUBMATRIX_FLAG; 
    } 
} 
updateContinuityFlag(*this); 
} 

cv::Mat::col()將返回一個新cv::Mat,它需要調用構造函數。
上面的構造函數用於構造cv::Mat以及另一個cv::Mat參考和cv::Range
請注意,data字段不是data字段的副本m的(m是傳遞給構造函數的參數)data

所以,我的問題..
abdata場是不同的!