opencv中图像复制的坑

事情是这样的,我想把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
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值