目录
1 图像的深拷贝与浅拷贝的介绍
首先先来理解一下,是什么时图像的深拷贝和浅拷贝。
众所周知,在C++的内存管理中,对一个变量进行复制,有两种情况,一种是浅拷贝、一种是深拷贝。浅拷贝:将原对象的引用直接赋给新对象,新对象只是原对象的一个引用,如果改变新对象,原对象也会发生改变。深拷贝:在堆区内存中,重新申请空间来存储数据。改变新的对象时,原来的对象不会发生改变。
那么在利用opencv进行图像处理时,是否也会有这种情况,答案是肯定的,在对图像进行复制时,同样会发生深拷贝和浅拷贝的现象。在进行浅拷贝时,如果对新图像进行操作,原图像也会发生变化,这就是图像的浅拷贝。而如果对新图像进行操作时,原图像不会发生变化,这就是深拷贝。
2 图像的深拷贝与浅拷贝的API详解
2.1 图像浅拷贝
很多人在进行图像处理时,会直接使用以下操作。
Mat src = imread("lena.png");
Mat src1 = src;
cvtColor(src1,src1,COLOR_BGR2GRAY);
这时就会产生一种现象,就是你感觉好像只是对是是src1图像进行了转灰度图像,其实在这个过程中,原图像也进行了转灰度的操作,这就是图像的浅拷贝。因此我们在图像处理过程中,应该尽量避免浅拷贝的操作,以免出现一些不可知的错误或者操作。
2.2 图像深拷贝
为了避免浅拷贝带来的影响,opencv中封装了对图像进行深拷贝的API函数,我们不用再自己申请一个堆区空间,然后将图像拷贝过去,只需要调用API函数即可。图像处理中的深拷贝的API函数有clone()和copyTo()两种,两个函数用法不同,但是效果基本一致。
Mat src = imread("lena.png");
//clone的用法
Mat src1 = src.clone();
cvtColor(src1,src1,COLOR_BGR2GRAY);
//copyTo的用法
Mat src2;
src.copyTo(src2);
3 图像的深拷贝与浅拷贝的代码实现
在代码运行后,我们可以看到,原图像在深拷贝之后没有发生任何变化,但是在浅拷贝之后,却发生了和浅拷贝图像一样的操作。
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{
//读取图像
Mat src = imread("lena.png");
if (src.empty())
{
cout << "could not load image" << endl;
}
//clone的用法
Mat src1 = src.clone();
cvtColor(src1, src1, COLOR_BGR2GRAY);
//copyTo的用法
Mat src2;
src.copyTo(src2);
cvtColor(src2, src2, COLOR_BGR2GRAY);
imshow("原图", src);
//浅拷贝
Mat src3 = src;
cvtColor(src3, src3, COLOR_BGR2HSV);
imshow("浅拷贝后的原图", src);
imshow("浅拷贝", src3);
imshow("clone", src1);
imshow("copyTo", src2);
//显示时间
waitKey(0);
return 0;
}