首先说说,本人发这篇文章没有任何的恶意,仅供学习交流,在校研三学生,学数字图像处理,搞这些东西完全是好玩,自己跟那些大虾肯定没法比,只是希望大家多拍砖,我才能进步……
先看看这款游戏验证码的原图像: 原始图像的特点是有些字符有粘连,有些没有粘连,还存在扭曲,下面就这些特点一一说明我的识别方式
1.二值化。 原图像是索引图像,转成灰度图像后只有集中颜色,取出黑色像素点为目标区域,其他为背景白色就二值化了,这个没什么难度
这张是二值化切割后的图像 ,图像只存在了黑白两种颜色,为了识别首先要提取模板,就是用来匹配的模板库
2.提取模板。我提取模板的方式很简单,比如因为有些字符没有粘连,比如y字符在这张图像中是没有粘连的,所以我直接提取连通区域来获得模板,当然这样需要大量的样本。这时候大家肯定要说字符存在扭曲,提取的模板有什么用,嘻嘻,下面就会说到怎么用扭曲的模板。
3.提取出来的模板如下:.我只取了一部分,除了i j字符上面有点 比较难搞定外,其他的字母基本都可以用这 个办法获得模板
下面我就用y字符来做为例子说明如何识别:模板如下:
4.匹配模板,说的专业点就是求最近邻,就是原图像中那块位置图像的特点和模板最接近,我采用的是distance map,对模板y得到的distance map如下
发现没有,颜色越深的地方表示离字符越近,越浅的地方表示离字符越远
下面来说明distance map图,以目标区域就是字符y为集合A,其他白色的地方为集合B,求得B中的每个像素点到集合A的距离,取最小值作为B中当前像素点的灰度值就得到了distance map
在原图像中从第一行第一个像素点开始,取得和模板大小相同的图像区域S,开始求得S和模板的相识程度(其实就是相似度,这个相似度有多种求法,我用的比较简单),就是计算s中黑色像素点地方对应distance map中的灰度值的和,当然这个和肯定是越小越好(如果没明白为什么越小越好说明没看懂distance map的原理哦)
最小值的地方就认为是最匹配的地方如下图
5当然这样只是检测出的单个字符,要识别出整个图像中的验证码只需要在模板中选4个匹配的最小值即可,最小值对应的模板即为识别出的字符,这个我将会继续完善,等待我的结果
另外:如果没有连通区域怎么提取模板,看这个图,我们取原图像每列黑色像素的个数作为纵坐标,列数作为纵坐标,得到下图
(波谷用蓝色*标记),取四个最低的波谷,标记到原始验证码图像上,用红色点标记,大部分字符会切割错误,但是还是有小概率字符会切割准确,比如这幅图像中的字符t,如果字符全部粘连的话,除了这个方法切割取得模板,好像我暂时想不到其他的好办法,希望各位大虾指点……
下面给出部分简单的验证码预处理吧,就是得到模板