如果a是cv :: Mat和cv :: Mat b = a.row(1),那么两个cv :: Mat实例之间有什么区别?

时间:2014-09-23 08:54:02

标签: c++ opencv

  

Mat a =(Mat_(3,3)<<<<< 1,0,0,0,1,0,0,0,1);
  cv :: Mat b = a.row(1);

cv::Mat有一个名为data的字段,它是一个指向Mat的实际内存的指针。
我知道这是浅层副本,不会分配新内存来存储a.row(1) b中的元素。
ab将共享同一段记忆 data的{​​{1}}字段与b的{​​{1}}字段相同。

我的问题是:
如果a的{​​{1}}字段与data的{​​{1}}字段相同,那么datab之间有什么区别?
他们的a字段相同,但其他功能dataa不同!! 他们怎么知道这个?

1 个答案:

答案 0 :(得分:1)

我的假设是错的! 虽然没有分配新内存,但dataa的{​​{1}}字段不同!

以下是b中标题的摘要代码,其中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::Mat

  

cv :: Mat b = a;

a&n; b字段与data字段相同。 不会为a分配新的内存。

但是下面的代码呢?

  

cv :: Mat b = a.col(1);

这里是b的代码段,其中包含cv :: Mat函数的实现:

matrix.cpp

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的{​​{1}}字段的副本(data是传递给构造函数的参数){{1} }。

所以,对于我的问题..
 mm的{​​{1}}字段不同!