Opencv open cv中的copyto()和clone函数
当我们使用cv::Mat保存图像时,我们知道在Mat对象的标题中它有像素的目标(指向图像位置的指针),因此通过对Mat类中的另一个对象使用“复制到”函数,它是创建像素的单独副本还是指向同一内存位置?Opencv open cv中的copyto()和clone函数,opencv,Opencv,当我们使用cv::Mat保存图像时,我们知道在Mat对象的标题中它有像素的目标(指向图像位置的指针),因此通过对Mat类中的另一个对象使用“复制到”函数,它是创建像素的单独副本还是指向同一内存位置?.copyTo和.clone()将同时(深度)复制像素数据,而不仅仅是标题,因此在大多数情况下,它将分配新内存,在更多情况下,不会共享源的内存 但是,如果目标矩阵已分配内存,并且图像大小和类型与新源相同,.copyTo将不会分配新内存,而是(深度)将像素数据复制到已分配的内存中 例如: 此代码将为目
.copyTo
和.clone()
将同时(深度)复制像素数据,而不仅仅是标题,因此在大多数情况下,它将分配新内存,在更多情况下,不会共享源的内存
但是,如果目标矩阵已分配内存,并且图像大小和类型与新源相同,.copyTo
将不会分配新内存,而是(深度)将像素数据复制到已分配的内存中
例如:
此代码将为
目标分配新内存
,并将源的像素复制到其中,因此源和目标不会共享内存
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%确定,我没有测试)共享内存,因为目标可能没有分配新内存,并且源和目标以前使用相同的内存。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!
好的,
.clone()
将始终分配新内存。.copyTo
和.clone
之间的另一个区别是可以在.copyTo
中使用掩码
还有一件事需要提及:.clone()
将始终创建一个连续的矩阵,即使原始矩阵在每个像素行的末尾有额外的字节,这些字节不包含任何像素数据(例如,如果每行字节数不满足硬件优化的要求,可以使用此填充来启用硬件优化)。.copyTo
和.clone()
将同时启用(深度)复制像素数据,而不仅仅是标题,因此在大多数情况下,它会分配新的内存,在更多情况下,不会共享源的内存
但是,如果目标矩阵已分配内存,并且图像大小和类型与新源相同,.copyTo
将不会分配新内存,而是(深度)将像素数据复制到已分配的内存中
例如:
此代码将为目标分配新内存
,并将源的像素复制到其中,因此源和目标不会共享内存
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%确定,我没有测试)共享内存,因为目标可能没有分配新内存,并且源和目标以前使用相同的内存。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!
好的,.clone()
将始终分配新内存。.copyTo
和.clone
之间的另一个区别是可以在.copyTo
中使用掩码
还有一件事需要提及:.clone()
将始终创建一个连续的矩阵,即使原始矩阵在每个像素行的末尾有额外的字节,这些字节不包含任何像素数据(例如,如果每行的字节数不满足硬件优化的要求,可以使用此填充来启用硬件优化).thank u.。这件事清除了我的思想。thank u.。这件事清除了我的思想Hi Micka。你的问题:如果你将cv::Mat::copyTo
与掩码一起使用,那么掩码等于0的元素的输出矩阵中的像素会发生什么变化?当输出矩阵已经分配时,其行为是否与被分配时有所不同未初始化?我在文档或StackOverflow上找不到这种行为。很抱歉在评论中打扰您,但为了安全起见,我宁愿在评论中提问,也不愿在问题中提问:)谢谢。@rayryeng我还没有尝试过。这是一个有趣的问题!Mika先生。没问题:)我和Miki谈过,我还查看了copyTo
的源代码。我们的线程在这里:。基本上,如果将copyTo
与掩码一起使用,并且输出矩阵未初始化,则会创建输出以匹配输入的大小,并在复制之前设置为cv::Scalar(0)
。如果矩阵已初始化,则会制作矩阵的副本,并复制掩码中非零的元素。我想我会用setTo
来代替。谢谢你的回复:)嗨,米卡。问题:如果将cv::Mat::copyTo
与掩码一起使用,那么对于掩码等于0的元素,输出矩阵中的像素会发生什么变化?与未初始化的输出矩阵相比,已分配的输出矩阵的行为是否有所不同?我在文档或StackOverflow上找不到这种行为。很抱歉在评论中打扰您,但为了安全起见,我宁愿在评论中提问,也不愿在问题中提问:)谢谢。@rayryeng我还没有试过。这是一个有趣的问题!米卡先生。没问题:)我和Miki谈过,我还查看了copyTo
的源代码。我们的线程在这里:。基本上,如果将copyTo
与掩码一起使用,并且输出矩阵未初始化,则会创建输出以匹配输入的大小,并在复制之前设置为cv::Scalar(0)
。如果矩阵已初始化,则会制作矩阵的副本,并复制掩码中非零的元素。我想我将使用设置为。感谢您的回复:)