inline
Mat Mat::clone() const
{
Mat m;
copyTo(m);
return m;
}
void Mat::copyTo( OutputArray _dst ) const
{
......//此处省略代码
_dst.create( dims, size, type() );//此处创建了图像存储的新内存
Mat dst = _dst.getMat();//dst由getMat进行初始化
if( data == dst.data )
return;
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t sz = it.size*elemSize();
for( size_t i = 0; i < it.nplanes; i++, ++it )
memcpy(ptrs[1], ptrs[0], sz);//该处为每个内存像素的复制
}
}
Mat UMat::getMat(int accessFlags) const
{
if(!u)
return Mat();
// TODO Support ACCESS_READ (ACCESS_WRITE) without unnecessary data transfers
accessFlags |= ACCESS_RW;
UMatDataAutoLock autolock(u);
if(CV_XADD(&u->refcount, 1) == 0)
u->currAllocator->map(u, accessFlags);
if (u->data != 0)
{
Mat hdr(dims, size.p, type(), u->data + offset, step.p);
hdr.flags = flags;
hdr.u = u;
hdr.datastart = u->data;
hdr.data = u->data + offset;
hdr.datalimit = hdr.dataend = u->data + u->size;
return hdr;
}
else
{
CV_XADD(&u->refcount, -1);
CV_Assert(u->data != 0 && "Error mapping of UMat to host memory.");
return Mat();
}
}
由源码可以看到,clone底层还是调用的copyTo函数实现的。Mat类的拷贝构造函数只是把数据指针等进行了赋值,没有开辟新的内存进行数据的存储。
inline
Mat::Mat(const Mat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
u(m.u), size(&rows), step(0)
{
if( u )
CV_XADD(&u->refcount, 1);
if( m.dims <= 2 )
{
step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
dims = 0;
copySize(m);
}
}