opencv中图像复制的坑

来源:互联网 发布:阿里云rap 编辑:程序博客网 时间:2024/04/29 05:57

事情是这样的,我想把IplImage转换到Mat,然后使用Mat做相关的处理,我是这么干的:

IplImage *tmpCutImg=cvCreateImage(cutSize,srcImage->depth,srcImage->nChannels);GetImageRect(srcImage,iRect,tmpCutImg);Mat cutMat(tmpCutImg);cvReleaseImage(&tmpCutImg);//释放IplImage的内存//显示Mat图像imshow("cutMat",cutMat);waitKey(1);

然后就发现跪掉了,显示的图像根本是一张乱码图片,后来发现是因为使用

Mat cutMat(tmpCutImg);

将IplImage转换为Mat时,Mat和IplImage共用数据区,在显示Mat之前就将tmpCutImg释放掉,Mat中的数据就变成随机的了,显示就成乱码了。所以正确的做法应该是在使用完毕Mat后再释放tmpCutImg。

同样的,使用Mat的构造函数进行Mat的构造也会是这种情况,产生的新的Mat会与原来的Mat公用相同的数据区。如下所示:

Mat A=imread("test.jpg");Mat A(B);

上面的操作构造出来的B会和A共用数据区,如果对B的数据区进行了操作,A的内容也会变化,因此如果想要复制全新的独立的Mat,要使用如下方式:

Mat B=A.clone();

还有一个函数是

void Mat::copyTo(OutputArray m, InputArray mask) const

这个函数的用法跟clone()的关系看了下面的代码就明白了:

inline Mat Mat::clone() const{  Mat m;  copyTo(m);  return m;}

所以如果不提供mask,那么clone()与copyTo()的功能是一样的,而不同的是copyTo()拷贝Mat时只拷贝mask不为零的位置,且mask的类型必须为CV_8U

1 0
原创粉丝点击