open cv中的copyto()和clone函数

Sha*_*ana 1 opencv

当我们使用 cv::Mat 保存图像时,我们知道在 Mat 对象的标题中,它具有像素的目标(指向图像位置的指针),因此通过使用复制到 Mat 类中的另一个对象的功能,它会创建一个单独的副本的像素或指向相同的内存位置?

Mic*_*cka 6

.copyToAND.clone()将(深度)复制像素数据,而不仅仅是标题,因此在大多数情况下它将分配新内存,在更多情况下不会共享源的内存。

但是,如果目标矩阵已经分配了内存并且图像大小和类型与新源相同,.copyTo则不会分配新内存而是将像素数据(深度)复制到已经存在的分配内存中。

例如:


此代码将为源分配新内存destination并将源的像素复制到其中,因此源和目标不会共享内存。

cv::Mat source = cv::imread(...);
cv::Mat destination;
source.copyTo(destination);
Run Code Online (Sandbox Code Playgroud)

此代码将使用较早分配的内存,但仍将像素复制到目标,因此.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);
Run Code Online (Sandbox Code Playgroud)

这段代码可能(不是 100% 确定,我没有测试它)共享内存,因为目标可能不会分配新内存,源和目标在 .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!
Run Code Online (Sandbox Code Playgroud)

afaik,.clone()将始终分配新内存。.copyToand之间的另一个区别.clone是可以使用maskin.copyTo


另一件要提到的事情:.clone()将始终创建一个连续矩阵,即使原始矩阵在每个像素行的末尾有额外的字节不包含任何像素数据(此填充可用于例如启用硬件优化,如果数字每行的字节数不满足硬件优化的要求)。

  • 嗨,米卡。给你的问题:如果你使用带有掩码的 `cv::Mat::copyTo`,那么掩码等于 0 的元素的输出矩阵中的像素会发生什么变化?与未初始化相比,已分配输出矩阵时的行为是否有所不同?我在文档或 StackOverflow 上找不到这种行为。很抱歉在评论中打扰您,但为了安全起见,我宁愿在评论中提出问题,也不愿提出问题:) 谢谢。 (2认同)
  • 米卡先生。没问题:)我和 Miki 交谈过,我还查看了 `copyTo` 的源代码。我们的线程在这里:http://stackoverflow.com/questions/31443288/opencv-mat-in-function-return-and-using-copyto/31443544?noredirect=1#comment70735168_31443544。基本上,如果您使用带有掩码的“copyTo”并且输出矩阵未初始化,则会创建输出以匹配输入的大小,并在复制之前将其设置为“cv::Scalar(0)”。如果初始化了矩阵,则会创建矩阵的副本,并复制掩码中非零的那些元素。我想我会使用 `setTo` 来代替。 (2认同)