1. 引言
随着互联网的极度开放,网络爬虫技术可以肆意获得任意公开的数据,网络的安全问题也日益突出,其中设置人类可读容易机器破解难的验证码在一定程度上可以阻止肆意的网络爬虫技术。验证码CAPTCHA起源于美国卡内基梅隆大学的一个科研项目,原意为全自动区分计算机和人类的图灵测试是一种区分用户是人类还是计算机的公共自动程序。当用户要对网络站点进行用户注册、用户登录或非登录式留言回复时,均需先正确填写网站提供的验证码,并通过网站服务器验证后,才能顺利完成各种操作。验证码技术在增强网络安全方面起到了重要作用。
目前的验证码识别在国内外已成为热门领域,其理论体系日渐完善。Per-Olal对验证码提取特征并用神经网络训练方法对一种简单验证码进行识别。2005年Edward等通过将字符旋转至水平并对单个字符应用小波滤波结果作为特征,以接近100%的识别率破解了验证码。同年Kumar和Patrice的研究表明,在验证码识别中,验证码图形字符分割比识别更难,一旦正确将字符逐个分开,运用机器学习算法就可以轻易解决识别问题。然而至今没有一种通用有效方法解决字符分割难题。2008年Jeff Yan等以高达90%以上的识别率破解了微软2007年使用的验证码 [1] ,对于有单个字符的干扰线的字符去除干扰线识别提出了解决的方法,对于这种长的和字符具有相同的像素宽度的、字符颜色一致的干扰线目前没有很好的解决方法。2005年程治国,刘允才 [2] 提出一种通用的去除文字图像中干扰线的算法利用图形学的理论,采用改进的最短路径算法和方向偏移算法检测干扰线。非粘连的正常排列有一定空间字符的分割可以通过二值化后的图像像素的竖直投影直方图来分割字符,但是对于一些扭曲变形斜着排列的字符就不适用,但可以用基于上下连通区域法分割字符,CFS (Color flooding segment)对于彩色填充分割算法适用于具有区域连通性的验证码。粘连字符分割可以采用滴水算法进行字符的分割 [3] ,有效避免了字符的过分割。汪洋等 [4] 采用最近邻KNN算法破解了少数银行网站的验证码。殷光、陶亮 [5] 提出了一种SVM验证码识别算法通过采用支持向量机比模板匹配算法识别准确率高。陈超、毛坚桓等 [6] 采用了卷积神经网络对铁路货运网站的验证码进行识别,使用深度学习方法对字符集进行训练优化网络参数。一些大的开发平台提出使用深度学习直接对网站验证码进行学习,对于这种手写各种形状标记验证码训练样本的数据量巨大。
2. 彩色验证码二值化
本文主要针对一些手写扭曲、抖动变换的验证码进行研究,包括某些字符涂抹的颜色点分布不均和同一字符大小不一、扭曲、抖动不同等特征。验证码图像如图1所示其分辨率统一为160*70像素,验证码特点彩色带干扰线、人眼不好识别,具有任意手写、抖动的特征,每个单个字符的形状特点不同,见图1。
对彩色验证码识别前,需将验证码码图像预处理,包括彩色图像灰度化与灰度图像二值化,如果直接对彩色图像自适应阈值二值化,可能会过滤掉某一个亮度和背景相差不大的字符信息,本文采用了红、绿、蓝三通道分别二值化,并取每个通道的最大值作为二值化的图像,使用此种方法对彩色图像进行二值化没有过滤掉有用的字符,见图2。
3. 彩色验证码字符分割
彩色验证码二值化处理后,采用CFS区域连通对字符进行分割,以提取图像中每个字符作为卷积神经网络层输入。根据图像的特点本文采用区域连通性算法对验证码进行分割。本文提到的区域连通算法以种子填充算法为基础,通过算法预先设定种子点,从该种子点出发,经过搜索标记验证码的所有像素点,将与预定义的性质相似如像素一致,找到种子点周围的8邻域像素一致的点加入到该种子队列中,来生长这些区域。区域连通算法也可通过沿着水平x轴依次扫描所有的像素点,找到字符像素,标记为1,找到标记为1的像素的上、下、左、右、四个对角线八邻域标记为1,依次标记水平字符像素点。纵向依次扫描水平像素点,找到字符标记像素点依次进行标记,发现周围八邻域按照标记的像素点值进行标记,再对已标记的像素点重新进行扫描进行合并同一区域的字符。对分割后字符进行归一化,通过查找单个字符的上下左右边界来存储单个字符的位置。
如果合并标记的字符区域为4个,直接进行卷积神经网络的输入端进行样本训练测试。
如果合并标记的字符区域大于4个,单个小的字符噪声应进行删掉,删掉后的字符区域为4个再进行卷积神经网络的输入端进行样本训练测试。
比较相邻两个区域的最小距离,如果相邻两个区域的最小两个点之间的距离小于s1,两个区域可以合并,如果相邻两个区域的最小两个点之间的距离大于s1并且小于s2,其中s1 < s2,可能是字符i或者j,如果相邻两个区域的最小两个点之间的距离大于s2,两个区域就可能是两个字符。s1和s2通过选取10,000张图片,40,000相邻两个字符的最近的两个点之间距离比较,挑选出由i和j的字符的点和无点连续的线最近的两个点之间距离比较,发现完整相邻两个字符之间的最短距离会最大为s2,i和j之间的点和无点连续的线最近距离会相对小为s1,相邻字符之间的最短距离小于s1,把分开的字符合并,见图3。
4. 彩色验证码卷积神经网络(CNN)模型
CNN是一个多层的神经网络 [7] ,每层由多个平面组成,每个平面有多个独立神经元,每个特征图通过交叠滑动方法,在离散上计算局部和,其操作等价于连续上的卷积,即卷积网络Yann等提出了基于CNN的文字识别系统LetNet-5 Patrice等提出了简化的CNN,见图4。
本文采用CNN进行验证码训练和识别。

Figure 2. Result of CAPTCHA binary by threshold
图2. 彩色验证码二值化结果

Figure 3. Connect district segmentation of CAPTCHA
图3. 彩色验证码连通区域分割

Figure 4. Topology structure of CNN
图4. 卷积神经网络的拓扑结构
验证码CNN拓扑结构如图4所示图中自下至上分别为卷积0层、子采样层、卷积四层。各层神经元与连接数如表1所示。
C1层是一个卷积层,由6个特征图Feature Map构成。特征图中每个神经元与输入为3 × 3的邻域相连。特征图的大小为18 × 18,这样能防止输入的连接掉到边界之外(20 − 3 + 1 = 18)。C1有60个可训练参数(每个滤波器3 × 3 = 9个unit参数和一个bias参数,一共6个滤波器,共(3 × 3 + 1) × 6 = 60个参数),共60 × (18 × 18) = 19,440个连接。
S2层是一个下采样层,有6个9 × 9的特征图。特征图中的每个单元与C1中相对应特征图的2 × 2邻域相连接。S2层每个单元的4个输入相加,乘以一个可训练参数,再加上一个可训练偏置。每个单元的2 × 2感受野并不重叠,因此S2中每个特征图的大小是C1中特征图大小的1/4 (行和列各1/2)。S2层有12 (6 × (1 + 1) = 12)个可训练参数和2430 (9 × 9 × (2 × 2 + 1) × 6 = 2430)个连接。
C3层也是一个卷积层,它同样通过3 × 3的卷积核去卷积层S2,然后得到的特征图就只有7 × 7个神经元,但是它有16种不同的卷积核,所以就存在16个特征图。C3中每个特征图由S2中所有6个或者几个特征图组合而成。C3的前6个特征图以S2中3个相邻的特征图子集为输入。接下来6个特征图
表1. 各层神经元与连接数
以S2中4个相邻特征图子集为输入。然后的3个以不相邻的4个特征图子集为输入。最后一个将S2中所有特征图为输入。这样C3层有6 ×(3 × 9 + 1) + 6 ×(4 × 9 + 1) + 3 ×(4 × 9 + 1) + (9 × 6 + 1) = 556个可训练参数和151,600 (7 × 7 × 556 = 27,244)个连接。
S4层是一个下采样层,由16个3 × 3大小的特征图构成。特征图中的每个单元与C3中相应特征图的2 × 2邻域相连接,跟C1和S2之间的连接一样。S4层有32个可训练参数(每个特征图1个因子和一个偏置16 × (1 + 1) = 32)和720 (16 × (2 × 2 + 1)× 3 × 3 = 720)个连接。
C5层是一个卷积层,有120个特征图。每个单元与S4层的全部16个单元的3 × 3邻域相连。由于S4层特征图的大小也为3 × 3 (同滤波器一样),故C5特征图的大小为1 × 1(3 − 3 + 1 = 1):这构成了S4和C5之间的全连接。C5层有17,400 (120 × (16 × 3 × 3 + 1) = 17400由于与全部16个单元相连,故只加一个偏置)个可训练连接。
经分析:验证码字符0-9大小字符A-Z (无I),小写字母为a、b、d、e、f、g、h、i、j、l、m、n、q、r、t、u与大写字母差别很大,共选择51个字符进行样本训练及测试。本文通过查找输出字符输出概率的最大值来判定输出的字符。
5. 实验验证
采集的样本量过多,本文只选择一小部分样本进行训练和测试每个字符采集的分割样本都在100个以上,共有样本5100个,其中随机选择80%的样本作为训练样本,20%的测试样本,在样本分割正确的情况下,基本上都能识别出字符。测试环境平台使用Intel酷睿i3处理器和Windows 7操作系统,在训练次数为50次,训练集和调整值的误差已经几乎为0。
由表2可见,通过本文采用的方法在没有彩色干扰线的情况下,大部分字符基本上都都能识别出来,在目前已有的训练和测试样本5100个小样本的情况下,字符6和字符b、字符9和字符g、字符A和字符4一些比较相近的手写体各色各样可能会存在误识别的情况,在实际大量验证码测试的情况下,在存在彩色干扰线的情况下四个字符分割识别准确率能达到50%以上,为继续丰富训练测试样本库,再进一步的验证中在应用程序中建立51个文件夹用来存放已识别的字符,找到识别错误的字符放到正确的样本库中,建立大的样本模型库。未来需要进一步对有彩色的干扰线的字符进行分割、训练、识别,也可以使用深度学习的方法不分割字符直接对验证码进行字符标记,前期的字符标记需要采集并进行大量的标记、增加人为标记的工作量,对卷积神经网络的参数进行调整、训练,每一个输出的都是四个51个字符的最大概率的输出。
通过对该验证模型在训练次数为50次,蓝色是训练集,红色是调整值集合。第一幅图是训练次数为50次,训练集和测试集实际对象的真实值,第二幅图训练次数为50次,迭代1次时,训练集和调整值的误差在50次很大,第三幅图训练次数为50次,迭代5次时,训练集和调整值的误差在50次已经几乎为0,见图5。

Table 2. Part of CAPTCHA’s image recognition result
表2. 部分验证码图像识别结果
6. 实验结论
本文主要针对抖动的、扭曲的、涂色不均匀的类似手写的验证码进行研究,包括彩色验证码的二值化、彩色验证码的区域连通分割,使用深度的卷积神经网络对字符进行训练和识别,通过对小样本量建立训练测试模型,基本上能正确分割识别出验证码的字符,未来主要使用该算法采集大的样本进行训练测试,建立大的样本训练测试模型,提高识别的准确率。目前对于带彩色的干扰线和和字符颜色一致的验证码还没有很好的解决办法,未来研究的方向是对干扰线和字符颜色一致的验证码进行自动识别。
基金项目
吉林省科技发展计划项目重大科技成果转化项目20170301005GX。