cv::Mat img1 = cv::Mat::zeros(cv::Size(100, 100), CV_8UC1);
cv::Mat img2 = img1;
cv::Mat img3 = img1.clone();
cv::circle(img1, cv::Point(50, 50), 20, cv::Scalar(255, 255, 255), -1);
std::string win_name = "img1";
cv::namedWindow(win_name, cv::WINDOW_KEEPRATIO);
cv::imshow(win_name, img1);
win_name = "img2";
cv::namedWindow(win_name, cv::WINDOW_KEEPRATIO);
cv::imshow(win_name, img2);
win_name = "img3";
cv::namedWindow(win_name, cv::WINDOW_KEEPRATIO);
cv::imshow(win_name, img3);
cv::waitKey(0);
运行结果如下:
图像深拷贝clone()
与浅拷贝=
由上面代码运行结果可以看出,如果不使用clone()
函数进行深拷贝,而是直接使用=
,那么你对图片的操作会影响所有=
构造的cv::Mat
。
并且,在定义函数时,不管你对cv::Mat
类型参数加不加引用符号&
,都是一样,即,函数内对图像的操作,会直接修改该图像。
如果使用了clone()
,那么就是一个新图像,对原先的图像进行操作不会影响clone()
的图像.
clone()
是完全的深拷贝,在内存中申请新的空间
copyTo()
可以是深拷贝,但是在不重新申请内存时就是浅拷贝:
copyTo 也是深拷贝,但是否申请新的内存空间,取决于dst矩阵头中的大小信息是否与src一至,若一致则只深拷贝并不申请新的空间,否则先申请空间后再进行拷贝.
用法:
Mat A = Mat::ones(4,5,CV_32F);
Mat B = A.clone() //clone 是完全的深拷贝,在内存中申请新的空间,与A独立
Mat C;
//此处的C矩阵大小与A大小不一致,则申请新的内存空间,并完成拷贝,等同于clone()
A.copyTo(C)
Mat D = A.col(1);
//此处D矩阵大小与A.col(0)大小一致,因此不会申请空间,既然不申请空间,
// 那么Mat D = A.col(1);的等号=就说明,A改变了会影响D的值。
//而是直接进行拷贝,相当于把A的第0列赋值给第1列
A.col(0).copyTo(D)