opencv不同环境下output不一致的一种场景

现象

opencv在c++和python中得到的结果不一致,即使是相同的语言相同的环境也可能得到不同的结果。

在做一个视觉项目时,其中有使用opencv,开发过程中我会先使用python写出基本的代码进行测试,可行的话再用c++(qt)复写一遍,本机测试完成后上传到服务器实机测试,一开始开发过程还算正常,后面就发现,服务器上有些图片识别的有问题,遂将有问题的图片都过程保存成 xxx.jpg,然后拉到本地看看啥问题,结果本地识别起来又没问题,甚至于有的时候,使用python处理后得到的中间结果再用c++继续处理就会出现和只用python处理的结果不一样。

这种情况并不普遍,几千张图片可能出现几个异常的情况。拉下来后本地又识别得没问题。

排查

一开始以为是缓存的原因,但是仔细重构代码后排除了这种可能

然后以为是并发的原因,因为之前也出现过一次使用qt出现的并发问题,多线程下一个野指针出现的问题,也是小概率出现,也是折腾了很久才解决。

反正就是搞了很久,还是无法百分百确定是不是并发造成的,于是想想是不是其他原因

甚至于我将每张出问题的图片的每个中间处理过程都保存下来和本地进行对比,输入一样(目视)但结果就是会出现不一致

最后,我将每张图片都保存后让程序进行重放(按原来顺序重新检测),经过对比发现,不是随机出现的,遂确定不是并发导致的,于是我将出问题的图片单独进行检测,奇迹出现了,不管是本机还是服务器,检测结果都一致了,我又试了多次,确实是一致的。

我的代码中,出问题的地方主要是霍夫圆检测上(HoughCircles),该函数基于Canny算子做边缘检测,然后我发现之前出问题的图片,虽然输入的图像目视是一样的,但Canny处理后的结果会出现些许不同。虽然不同的地方还是比较少,但我觉得霍夫圆检测对参数还是比较敏感的。

然后我突然想到,之前不一致的情况都经过了一次中间过程的存储,然后再进行读取的,那问题一定是出现在存储格式上。

解决

问题就出现在jpg这种图片格式上,其实从一开始我就有想到这个东西,因为我一直对傅里叶变换比较感兴趣,而jpg就是用该原理实现的,但不知道怎么的,后面忘了这茬了。将图片以位图的形式保存就好了。

// 原来的
cv::imwrite("img", "xxx.jpg")
// 现在的
cv::imwrite("img", "xxx.bmp")

后记

有一说一,c++/qt 好像做什么都比较麻烦,还不好debug,用惯了jetbrain的ide再用qtcreator感觉就像回到了上个世纪。

Leave a Comment