编程经验:几个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类型数据,内存必然泄露。
----------------------------------------------------------------------------------------------------------

发布了42 篇原创文章 · 获赞 192 · 访问量 50万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览