【opencv】图像cv::Mat浅拷贝=与深拷贝clone()、copyTo()

  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();

//此处D矩阵大小与A.col(0)大小一致,因此不会申请空间,既然不申请空间,
// 那么Mat D = A.col(1);的等号=就说明,A改变了会影响D的值。
//而是直接进行拷贝,相当于把A的第0列赋值给第1列
A.col(0).copyTo(D) 

おすすめ

転載: blog.csdn.net/u011754972/article/details/121829795