opencv copyto()和clone函数

smdncfj3  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(93)

当我们使用cv::Mat保存图像时,我们知道在Mat对象的头部中,它有像素的目的地(指向图像位置的指针),所以通过使用copy函数到Mat类中的另一个对象,它是创建像素的单独副本还是指向相同的内存位置?

13z8s7eq

13z8s7eq1#

.copyTo.clone()都将(深度)复制像素数据,而不仅仅是头部,因此在大多数情况下,它将分配新的内存,甚至在更多情况下,源内存将不会共享。
但是,如果目标矩阵已经分配了内存,并且图像大小和类型与新源相同,则.copyTo不会分配新内存,而是将像素数据(深度)复制到已经存在的已分配内存中。
例如:
这段代码将为destination分配新的内存,并将源的像素复制到其中,因此源和目标不会共享内存。

cv::Mat source = cv::imread(...);
cv::Mat destination;
source.copyTo(destination);

这段代码将使用先前分配的内存,但仍将像素复制到目标,因此.copyTo不会分配新内存,但像素被复制,因此源和目标不会共享内存。

cv::Mat source = cv::imread(...);
cv::Mat destination = cv::Mat(source.size(), source.type()); // this will allocate memory fitting the data of source
source.copyTo(destination);

这段代码可能(不是100%确定,我没有测试过)共享内存,因为目的地可能不会分配新内存,而源和目的地在此之前使用相同的内存。

cv::Mat source = cv::imread(...);
cv::Mat destination = source; // now they use the same memory
source.copyTo(destination); // since destination size and type do fit source size and type, MAYBE no new memory is allocated!

afaik,.clone()将始终分配新内存。.copyTo.clone之间的另一个区别是可以在.copyTo中使用mask
还有一件事要提:.clone()将始终创建一个连续的矩阵,即使原始矩阵在每个像素行的末尾有额外的字节,这些字节不包含任何像素数据(例如,如果每行的字节数不满足硬件优化的要求,则可以使用此填充来启用硬件优化)。

相关问题