OpenCV 2.4.2 imdecode/cvDecodeImage 的 BUG及解决方案

OpenCV是很好用的开源库,不过,还是有一些BUG的~

比如,今天遇到的问题是,imdecode的执行速度很慢。

照理来说,imdecode是从内存解析一幅图像,应该比cvLoadImage还快(或者至少不慢)。

但实际上,执行的时候却是imdecode慢很多(一张图片要1秒以上)。而且很奇怪的是,在某些机器很快,某些机器就很慢。而且调用了不同版本的OpenCV速度也不同。

为什么呢?本着质疑的原则,开始查看OpenCV的源代码。

imdecode的实现在modules\highgui\src\loadsave.cpp中。结果,发现opencv也是先将内存数据写到文件然后再读取的……这不是偷懒么orz

不过,逻辑上没有问题,算法上却犯二了……OpenCV2.4.2及之前版本在实现这个函数的时候,申请了一个临时文件(C:\user\用户名\AppData\Local\Temp\下的ocvXXXX.tmp文件,其中XXXX是0~F的16进制数)。然后写这个文件,然后读。关键是,没有删除!原因是因为临时文件可能不存在(本意是如果形如ocvXXXX.tmp的文件都存在了,那么就不能再新建了,所以返回空不作操作,实际上不会走到这一步),所以最后不一定需要删除文件。于是写OpenCV的小朋友这里为了程序稳定就没有删除临时文件。如图所示:

temp2

结果就是:如果调用imdecode次数越多,速度越慢。超过65535次则每次需要枚举65535个临时文件是否存在。。这个时间对系统而言大致是1秒吧~

当然,写OpenCV的小朋友还是意识到了这个问题,至少2.4.5开始这部分代码就改成判断临时文件名是否为空,不为空则删除了。这样就不会产生临时文件堆积的问题了~

 

anyway,结论就是:

如果想从内存里面直接解析一幅图像,还是乖乖自己写到文件再读取吧~可以模仿opencv去向系统申请临时文件的说~(GetTempPathA和GetTempFileNameA函数)

那些戏剧性的事情~

1)高一暑假学游泳,属于刚刚能游50米的那种;然后高二开学学校举行游泳比赛,因为班级成员人数不足被拉去凑数(4×50接力)。。结果,一共就4个班凑齐了4个人游接力。因为我游得最慢,所以虽然我们班其它三个人速度不错,但是还是屈居第二。结果,戏剧性的一幕出现了,第一名的队伍被判犯规(好像是说中途碰到了泳池壁),被取消成绩,于是我们就成为了第一名……所以,我还是获得过游泳比赛冠军的:)虽然现在扔进水里就会被淹死了吧= =

2)高一参加科技节的凝胶滴定实验(生物),就是老师示范一遍,大家模仿一遍,看谁的实验结果最好看……按照班级顺序进行比赛的,所以到我们班(10班,最后一个)。其实大家都做得差不多。然后老师打分,结果好多都同分。这时候学生会的人就要老师给出一二三名,老师看了看评分表,然后看了看我们(只剩我们刚做完实验还没回班级),就说,那就他们第一吧:) 于是,就这么拿到了这个比赛的第一名= = 后来,班主任还让我用这个第一名去申请学校科技新苗,我觉得比较rp,所以就没申。