编程经验:几个OPENCV中挺有意思的BUG~

不写博客好长时间了,近期忙于实现论文中的算法,调试了一波又一波的bug,这个是最耗时的,本文分享一个我今天遇到的一个挺有意思的bug。

我用的是opencv2.4.9,运行320p的图像,一切正常,但是当我换成640p的图像,运行到一半,程序崩溃了,究其原因是内存泄露导致的,原来程序的占有的内存以每一帧3M的速度不断的攀升。我本想采用X64编译运行,可没想到用了一些该死的库文件,bug一批一批的跳出来。无奈,只能一步一步的寻找泄露的位置,经过最简单粗暴的任务管理器观察,原来都是opencv引起的。做此博客,希望大家能够少走弯路。

eg1. release()函数对CV_8U、CV_8S类型失灵
---------------------------------------------------------------
Mat tmp1       = Mat::zeros(hei, wid, CV_32F);
Mat tmp2       = Mat::zeros(hei, wid, CV_32F);
Mat left_gray  = Mat::zeros(hei, wid, CV_32F);
Mat right_gray = Mat::zeros(hei, wid, CV_32F);
Mat lGray      = Mat::zeros(hei, wid, CV_8U);
Mat rGray      = Mat::zeros(hei, wid, CV_8S);
tmp1.release(); // 内存释放成功
left_gray.release(); // 内存释放成功
lGray.release(); // 内存释放成功
tmp2.release(); // 内存释放成功
right_gray.release(); // 内存释放失败
rGray.release(); // 内存释放失败


换成
Mat lGray      = Mat::ones(hei, wid, CV_8U);
Mat rGray      = Mat::ones(hei, wid, CV_8U);
也不行


换种方式
lGray.create(hei, wid, CV_8U);
rGray.create(hei, wid, CV_8S);
也不行


再换种方式
Mat lGray(hei,wid,CV_8U,cv::Scalar(0,0,255));
Mat rGray(hei,wid,CV_8U,cv::Scalar(0,0,255));
也不行


那请问,怎么破才能行?


答案:如果变成下面这个样子
Mat lGray      = Mat::ones(hei, wid, CV_8UC2);
Mat rGray      = Mat::ones(hei, wid, CV_8UC3);
就行了!


结论:release函数对于CV_8U、CV_8S类型,或者是CV_8UC1、CV_8SC1类型的Mat矩阵,有BUG。
-----------------------------------------------------------------------------------------------------

eg2. 同样,相关函数一个都跑不掉,均有这个问题。
-----------------------------------------------------------------------------------------------------
Mat lGray, rGray;
Mat tmp1, tmp2;
Mat left_gray, right_gray;
lImg.convertTo( tmp1, CV_32F );
cvtColor( tmp1, left_gray, CV_RGB2GRAY );
tmp1.release();
left_gray.convertTo( lGray, CV_8U, 255 );
left_gray.release();
lGray.release(); // 内存释放失败
rImg.convertTo( tmp2, CV_32F );
cvtColor( tmp2, right_gray, CV_RGB2GRAY );
tmp2.release();
right_gray.convertTo( rGray, CV_8U, 255 );
right_gray.release();
rGray.release(); // 内存释放失败


如果改成CV_8UC3,会释放成功吗?
lImg.convertTo( tmp1, CV_32F );
cvtColor( tmp1, left_gray, CV_RGB2GRAY );
left_gray.convertTo( lGray, CV_8UC3, 255 );
rImg.convertTo( tmp2, CV_32F );
cvtColor( tmp2, right_gray, CV_RGB2GRAY );
right_gray.convertTo( rGray, CV_8UC3, 255 );
tmp1.release();
tmp2.release();
left_gray.release();
right_gray.release();
lGray.release(); // 内存释放仍旧失败
rGray.release(); // 内存释放失败


如果我这么写呢?
Mat tmp1       = Mat::zeros(hei, wid, CV_32F);
Mat tmp2       = Mat::zeros(hei, wid, CV_32F);
Mat left_gray  = Mat::zeros(hei, wid, CV_32F);
Mat right_gray = Mat::zeros(hei, wid, CV_32F);
Mat lGray      = Mat::ones(hei, wid, CV_8UC3);
Mat rGray      = Mat::ones(hei, wid, CV_8UC3);


lImg.convertTo( tmp1, CV_32F );
cvtColor( tmp1, left_gray, CV_RGB2GRAY );
left_gray.convertTo( lGray, CV_8UC3, 255 );
rImg.convertTo( tmp2, CV_32F );
cvtColor( tmp2, right_gray, CV_RGB2GRAY );
right_gray.convertTo( rGray, CV_8UC3, 255 );
tmp1.release();
tmp2.release();
left_gray.release();
right_gray.release();
lGray.release(); // 内存释放失败
rGray.release(); // 内存释放失败


convertTo简直是六亲不认啊!


那我该怎么办?
答案:没办法,将CV_8U换成其他类型吧
left_gray.convertTo( lGray, CV_32F, 255 );
right_gray.convertTo( rGray, CV_32F, 255 );

lGray.release(); // 内存释放成功

rGray.release();// 内存释放成功


convertTo可以对自身进行depth的转换,但是需要耗费额外的内存,同上,CV_8U无法释放,但是其余的均可以释放。

lGray.convertTo( lGray, CV_32F, 255 );


PS. 有个下采样函数pyrDown,这个函数对于任何类型的数据,均无法释放,奇葩。


结论,convertTo对uchar,char类型数据,内存必然泄露。
----------------------------------------------------------------------------------------------------------

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值