图像识别(2)—验证码篇

图像识别—验证码篇(2)

分割

分割就是把验证码切开,分成一个一个的字符,好方便识别的过程。现在的识别技术大多数都是单个字符去训练识别的,并不是说不可以整张的去训练识别,可是那样需要成吨的训练样本和时间,并且非常容易出现过拟合现象,so,我们还是老老实实的分割吧!毕竟我们都是初学者!

分割的方法有很多,对于这种字母互相没有粘连,而且水平位置波动不大的,我推荐大家使用感染分割法!这是一种最基础的分割方法!其他很多分割方法都是以它为基础的,后篇中我们会介绍到一些比较复杂的分割方法。感染分割法概述就是:首先找到水平位置上的一个中点,画一条直的横线,确保这条线可以穿过图片上的每一个字。然后通过从左到右去遍历这条线上的每一个点,每找到一个黑色的点,就把和他所有相邻的黑色点都拿出来,单独生成一张图片。很好理解吧!

图1

如图1所示,这就是我们遍历的点的行走轨迹,就这样一直遍历下去,就能分割出我们所有的字符啦!附上一段代码,仅供参考:

运行完毕之后,得到一个装满字符像素点的集合,字符我们算是切割出来了,下一步做什么呢?下面我们要为识别工作做准备啦!我们需要“归一化”。这是什么呢?

字符归一化是光学字符识别中的一个子步骤,给定一个字符区域,我们要做的就是将该区域内的字符归一化到一个标准模板大小,然后才能提取特征,并送给分类器做具体的识别。好的归一化算法可以尽量提高后续特征提取在同一类内的一致性。归一化算法大致分为四类:

1,归一化到标准模板大小

2,倾斜校正

3,笔画宽度归一化

4,字形归一化

归一化在日常工作中,是一个很重要的环节,会直接影响到识别的精度!简单的说,每一个准备识别的字符的图片都必须有统一的大小,且最好有统一的比划粗细、倾斜角度以及字体。图片大小取决于你训练样本的大小,在不丢失特征细节的基础上,越小越有利于提升识别的精准度!至于训练样本是什么,后面会讲到,开篇这一章,我们识别还没有用到机器训练,机器学习,神经网络之类的东东~对这部分感兴趣的同学一定要持续关注我哦!

我们这张验证码,归一化极其简单,只要保证你输出的每张图片的大小一样就好了!图片大小要多少合适呢?可不能用眼看啊!教你一个方法,多切一些图片,通过这些点集合中的最大行,最小行,最大列,最小列就能求出他们的高度和宽度,找一个最大的高度和最大的宽度,那就是这批验证码单个字符的宽和高啦!经过上述推算,单个字符大小为13*25。

先创建一张新的空白图片:

把我们刚刚得到了那个集合里面每个字符的点集一个一个的填进去涂黑,就正式切割完成了!填的时候记得放在正中间,给上下、左右都留出一样的距离就行了!

图2

识别

经过了那么多处理工作,终于可以开始识别了!这可是我们工作的重中之重!不过同学们依然不用担心,在我们初试牛刀这一章中,识别部分的难度那也是相当的简单亲民呐!让我们来认识一下机器学习界最简单的算法之一!KNN(K-Nearest Neighbor,“K最近邻”),先引用当下学习KNN用的最多的一张图,边看边讲:

图3

如图3,我用小学毕业就可以听懂的话来解释一下:假设我们要识别的字符是图中心的绿色圆形,如果K=3,最近邻的三个图形中三角形最多,那它就是三角形。如果K=5,那最近邻的5个图形中正方形最多,它就是正方形!当K再次变大,三角形和正方数量相同,那我们就要计算权重了,即距离越近权重分数越高,所以最终它就又被识别成三角形!很好理解吧!只需要把图中的二维距离替换成空间距离,也就是欧氏距离(欧几里得距离),这就是KNN的所有精华了。

下面咱们把KNN落实在代码里吧!多下载一些验证码,对验证码进行去噪和分割,尽可能多的得到分割之后的样本(如图2),然后挑选一批样本,尽量保证每一个字符的样本都可以覆盖到它的所有形态,我们选择的这个验证码是比较简单的,只有数字和字母,不会扭曲、旋转,大小也不会变化,所以并不需要太多的样本。事实上如果某个验证码比较复杂,需要大量样本去覆盖字符形态,KNN也就不适用了。经过人工筛选,我们得到一批这样的样本:

图4

仔细观察一下,会发现一个字符如果有多个样本,这些样本都有一些细微的不同。进行过机器学习的同学肯定表示,这点样本根本不够看!不过对于KNN来说,这就足够了!接下来我们对样本进行手工打标,意思其实就是手动的去修改每个样本的文件名。把文件名改成图像上的字符,如图4,后面还需要一个后缀,用于区别单个字符的多个样本。这一步是整体工作最简单也是最枯燥冗长的一个步骤,在后篇中,我们需要成千训练样本的时候,也需要一个一个的手工打标,这个步骤是跳不过去的,所以,呼基唤友,一起做吧!

下面上代码,第一步,先把我们制作的这些样本load进去:

上面这一步可以放在init里面去做,下面直接求距离:

通过这一步,我们已经得到了一个排好序的距离集合(distanckList),里面放着我们的被识别图片与所有样本之间的距离,后面要做的就很简单了吧!我们还需要两个参数:

k=5表示我们要分析的是集合(distanckList)里面的前5个数据,拿出前五个距离数据到,到距离权重对照表中卡一下,得到每个距离的权重,很容易就可以预测出这个字符是什么了吧?

最后再把每一个预测出来的数据拼接在一起,看,完整的验证码就识别出来啦!

总结

如果你也顺利的识别出整张验证码的结果,那恭喜你已经成功的迈入了图像识别的门槛,成为了一名初级解码师!可以去碾压各种低级的验证码了!从此以后图像识别在诸位心中也不再是不可逾越的高山

猜你喜欢

转载自blog.csdn.net/zhangbijun1230/article/details/81606530