上一篇介绍了如何降噪,这一篇介绍第二,三板斧,分割与识别。
分割图片,就好比切西瓜,先考虑最简单的情况,字符与字符之间没有粘连,且向X轴方向的投影也不重叠。这种情况下,只需从左向右扫描,便可知道每个字母在X轴上的投影范围,左侧一刀,右侧一刀,这两刀都是竖着切。然后再从上向下扫描,便可知道每个字母在Y轴上的投影范围,上面一刀,下面一刀,这两刀是横着切,四刀过后,便将图片切分好。
待分割图片:
切分后:
遇到像上面这样任人宰割的验证码,万事大吉,但更多的验证码的字母会出现粘连的情况,如果粘连的不是特别严重,且单个字母的宽度变化不大,那么可以考虑对粘连的字母进行平均分割。
更高级点的方法是用垂直像素直方图的统计方法分割,在X轴方向上,每个像素切一刀统计这一刀上的黑色像素的个数,最终得到一个垂直像素直方图,盗用一张图片:
通过波峰和波谷,可将图片顺利切分。如果粘连情况很严重,则可以考虑滴水法(太复杂,没用过,不介绍)
经过降噪,分割后,可以进行识别了。其实这之前还有一步标准化的过程,但如过验证码很简单,这一步也就可以省略了。
识别,我采用了BP人工神经网络,具体操作过程如下:
(1) 将单个图片规范成32*32的像素的图片,按2*2切分成16*16(256)个子局域,统计局域内的黑色像素的个数,由此得到一个256维的特征矢量。这个特征矢量就是输入层,
(2) 需要识别的字母种类是0-9的数字,因此,将目标输出值设置为一个10维的列向量,比如字母4所对应的列向量为[0,0,0,0,1,0,0,0,0,0] ,
(3) 设置隐含层为64,学习率为0.001,进行训练并保存训练结果
(4) 使用时,装载训练结果,将待识别的单个字符图片通过第一步转成256维的特征矢量并输入到神经网络中,最终会得到一个10维的输出,用这个输出同0-9各自所对应的特征矢量进行欧式距离计算,距离最近的那个字符就是识别的最终结果。
Python有封装的非常好的BP神经网络库,我使用的是pyneurgen,参考资料地址:
http://wenku.baidu.com/link?url=S6fnkPrMDqqCVeof_62tsS5vLHtHixnIK3H4uP9XccS7Qaak1hdLKZ6TYwq7WT_37ie_VNqvp0FEOi9uSEK_AY_c4vt14T33133DEAknKc7
基础理论部分,我没有上代码,因为项目里的代码很难拿出来做例子,接下来的文章,我会逐步的整理之前的代码,让大家一步一步跟着操作,最终得到一个满意的结果。