Mat数据类型的深拷贝与浅拷贝
1、深拷贝
opencv中深拷贝是在定义另外一个Mat数据类型的时候会重新开辟一块内存,把当前需要拷贝的数据放在新开辟的内存里面,这样就让这两个变量毫不相关,操作任何一个都不会影响另外一个,这就是所谓的深拷贝;举例如下:把其中一幅图片滤波之后都不会影响另外一幅图片
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp> //头文件
using namespace cv; //包含cv命名空间
using namespace std;
void main()
{
Mat test0 = imread("1.jpg",1);
//Mat test1;
//test0.copyTo(test1);//深拷贝方式1
Mat test1 = test0.clone();//深拷贝方式2
imshow("one",test1);
blur(test0, test0,Size(7,7));
imshow("the other",test1);
waitKey();
}
2、浅拷贝
浅拷贝和深拷贝不同,从名称就可以看出大致是什么意思,浅拷贝是运用到两个数据变量操作一块数据内存,相当于C++中的引用,把一个Mat变量浅拷贝给另外一个Mat变量后,操作这两个变量等价于操作同一块内存,所以这就叫浅拷贝;举例如下:
对其中的test0拷贝给test1后,马上滤波test1,发现test0在test1被滤波前后发生变化了。
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp> //头文件
using namespace cv; //包含cv命名空间
using namespace std;
void main()
{
Mat test0 = imread("1.jpg",1);
Mat test1 = test0;//浅拷贝
imshow("one",test0);
blur(test1, test1, Size(7, 7));
imshow("the other", test0);
waitKey();
}
3、push_back中的深拷贝与浅拷贝
当我们定义一个Mat类型容器放置不同的数据到里面以方便进行后续的处理时,就会用到push_back,这个函数用来往容器的尾端放置数据,但是本人在应用中遇到过一个问题,调试了好久才发现,没意识到深拷贝与浅拷贝。当定义一个Mat类型的全局变量和一个Mat类型的容器,全局变量用于存放发生变化的图像拼接后图片,每次拼接完后放到这个全局变量中,然后用该添加至Mat容器的尾端,这样当后面取出来发现,该容器内部的图片数据全是一模一样的最后一次放进去的图片。举例测试如下:
用深拷贝不会出现上述情况,而用浅拷贝就会出现上述情况。
#include <stdio.h>
#include <iostream>
#include <opencv2/opencv.hpp> //头文件
using namespace cv; //包含cv命名空间
using namespace std;
Mat pushtest0;
Mat pushtest1;
Mat pushtest2;
Mat pushtest3;
Mat test;
Mat aaaa;
int testint;
int num = 0;
void main()
{
vector<Mat> result;
Mat test0 = imread("2_meitu_2.jpg",1);
Mat test1 = imread("2_meitu_3.jpg",1);
Mat test2 = imread("2_meitu_4.jpg",1);
Mat test3 = imread("2_meitu_5.jpg",1);
Mat test00;
Mat test01;
Mat test02;
Mat test03;
while (true)
{
if (num == 0)
{
test0.copyTo(test);
//result.push_back(test.clone());//深拷贝
result.push_back(test);//浅拷贝
num++;
}
if (num==1)
{
test1.copyTo(test);
//result.push_back(test.clone());
result.push_back(test);
num++;
}
if (num==2)
{
test2.copyTo(test);
//result.push_back(test.clone());
result.push_back(test);
num++;
}
if (num == 3)
{
test3.copyTo(test);
//result.push_back(test.clone());
result.push_back(test);
num++;
}
if (num == 4)
{
result[0].copyTo(test00);
result[1].copyTo(test01);
result[2].copyTo(test02);
result[3].copyTo(test03);
break;
}
}
}