当我们使用cv :: Mat保存图像时我们知道在Mat对象的标题中它有像素的目的地(指向图像位置的指针)所以通过使用复制功能来创建Mat类中的另一个对象它是否创建单独的像素副本或指向相同的内存位置?
答案 0 :(得分:4)
.copyTo
AND .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%肯定,我没有测试它)共享内存,因为目标可能不会分配新内存,而源和目标使用相同的内存BEFORE .copyTo:
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
之间的另一个区别是在mask
.copyTo
的可能性
另外需要提及的是:.clone()
将始终创建一个连续矩阵,即使原始矩阵在每个像素行的末尾都有额外的字节而没有任何像素数据(这个填充可以是例如,如果每行的字节数不满足硬件优化的要求,则启用硬件优化。