2014-09-23 114 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场是不同的!