更新后代码下载链接在此!!!
点我下载
本文针对OpenCv入门人士,因为我也不是专门做图像的,只是为了完成一次模式识别的小作业。
主要完成的功能就是自动识别图片中的数字,图片包括正常图片,有划痕图像和有噪点图像。分别如下
先上图,看识别效果!
接下来开始来点干货了:
- opencv的安装与配置:这个要是展开讲可以再写一篇博文了,我当时什么都不会配个opencv麻烦死了,最后参考网上studio2012的配置方法成功了,在此略过。看到这里你的opencv还不能用的话,赶紧别往下看了,先把opencv配好再来吧!
- opencv基本图片操作:
- 因为opencv有2.0 和 3.0 的版本区别,所以网上搜到的函数或类型都是两种格式,建议用新版的,什么impImage* 类型的都是2.0版本的写法,我全部使用的是Mat。一定要统一好,不要一会新的一会旧的,会报错的。
- 读图片imread,显示imshow,等待waitKey等等,这些要先熟悉
- opencv的强大之处在于几乎所有的图像操作它都有现成的函数可供调用,非常方便。多谷歌,一定会有函数已经实现了你想完成的功能。
- 二值化:不论是原图还是有划痕或噪点的图,背景都不干净,这对识别的影响还是挺不好的,所以要先二值化,把黑白像素点区分的开一些。但是图片右侧明显要比左侧更暗,所以在阈值选取的时候比较难办,很难用一个固定的值将两部分图像都二值化得很理想,所以就用到了逼格更高的自适应二值化(adaptiveThreshold),tips:二值化前先直方图均衡一下效果会更好。
- 中值滤波:针对有噪点和有划痕的图像,中值滤波是非常好的处理方案,中值的参数可调,可以很好的消除噪音的影响。缺点就是参数不好调啊,调的想死。。
- 模板匹配:模板的来源可以是自己从待识别的图片中抠图,不过我们作业提供了模板图片,所以这一步就可以省掉了。opencv提供了非常强大的matchTemplate函数,可以将给定图片与模板按照你规定的计算方法计算一个相似度的值,并将对应的坐标存储下来,你需要做的只是将值比较大(或小,与你规定计算相似度的函数有关)的图像框出来即可
- 窗口扫描:为了提高识别率,我设定了一个窗口对原图进行扫描,扫描窗口的移动设定了一点规则,就是如果前一个窗口没有匹配到数字就微调窗口位置,如果匹配到数字就将窗口左轴移动到匹配到的数字的右侧,再重复扫描。
基本干货就这么多了,剩下的就是不断的调参数和扫描窗口的位置了,这个方法的缺陷就是针对不同的图片,参数和扫描窗都要变,比如来一张一行或三行的数字,那就必须修改扫描窗口的函数了,还有每一步的步长之类的,还是相当蛋疼的!
下面是部分核心代码
预处理,包括自适应二值化和中值滤波
void preProcess(){ //自适应二值化&中值滤波
Mat out;
//自适应二值化
adaptiveThreshold(source, source, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, adaptiveBiSize, adaptiveBiParam);
//中值滤波
namedWindow("binary");
imshow("binary",source);
waitKey(0);
medianBlur( source,