视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
基于字符的图片验证码识别算法的设计与实现
2025-09-29 22:29:55 责编:小OO
文档
基于字符的图片验证码识别算法的设计与实现

作者:陈以山 张勇

来源:《电脑知识与技术》2017年第01期

        摘要:验证码是各大网站用以防范计算机自动程序恶意攻击的手段之一。通过使用数字图像处理中的图片分割、开闭运算等手段,能够识别绝大部分网站的验证码。对验证码识别技术的研究,既能及早发现验证码的漏洞,也能对诸如车牌识别、手写识别等技术起到促进作用。

        关键词:验证码识别;数字图像处理;图片分割;图片开运算;模图片闭运算

        中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)01-0190-03

        1 研究背景

        验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Hunmans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分当前用户是人类还是计算机的自动程序。在测试中,用户需要根据程序生成的一个问题做出正确的回答,程序据此来判断该用户是人类还是计算机。验证码种类繁多,大体有基于字符的图片验证码、基于问答的验证码、声音验证码等。

        目前,应用最广泛的是基于字符的图片验证码,它具有容易产生、不受用户背景知识和文化差异的影响,且暴力破解的难度很大,使用主流的编程语言,很容易可以产生一个包含随机字母或者数字的图片。为了增加识别难度,在生成图片时,往往会加上诸多干扰因素,比如加上前景、背景,字符粘连,字符变形、歪斜等。

        验证码为互联网安全作出了很大贡献,但我们不能忽视验证码所存在的漏洞,研究验证码自动识别算法,能够及早发现验证码设计存在的漏洞,并在据此作出调整,以增加验证码的安全性。同时,验证码识别作为一种图灵测试,综合了数字图像处理、模式识别、人工智能等领域的研究成果,也对其他应用如车牌识别、手写文字识别等具有参考作用。

        本文所研究的验证码识别算法,主要分为图片预处理、字符分割、模式识别三个步骤。由于各个应用所使用的验证码识别难度不一样,需要根据具体的验证码特点,进行具体分析,这里选取了CSDN的验证码作为主要分析对象。

        2 图片预处理

        1) 彩色图片灰度化

        大部分彩色图像都是采用的RGB颜色模式,但是其并不能反映图像的形态特征,只是从光学的原理上进行了颜色的调配。灰度化的过程就是将有RGB三通道的彩色图像转化为灰度图像的处理,仅保留机器识别时所需要的必要信息,以便于后面的处理操作。在灰度化的过程中,一般是根据一定的系数将三维的RGB色彩降低为一维的灰度值。本人选取的灰度计算公式为:

        其中,R、G、B分别是像素点在三个颜色通道的值,Grey为该像素点对应的灰度值。具体计算方法为:依次读取图片每个像素点,获取其RGB值,取三者的平均值作为新图片对应像素点的灰度值。彩色图片灰度化后的结果如表1所示:

        2) 灰度图片二值化

        经过灰度化的图片,每个像素点的灰度值为0~255之间的任意数。由于验证码图片中背景色与字符颜色具有较大差异,可以通过设定阈值的方法,区分背景和字符。灰度值大于阈值的像素点,灰度值都设置为255,小于等于阈值的像素点,灰度值都设置为0,具体计算公式为:

        T值得选取在图片二值化过程中至关重要,选取适当的T,可以在一定程度上去除图片噪音,增强字符轮廓。为了更精确的获得图像信息,这里采用近似一维Means方法寻找二值化阈值,该方法的大致步骤如下:

        a. 设置一个初始阈值T=127

        b. 根据阈值将每个像素数据P分为字符数据G1和背景数据G2

        c. G1的平均值是M1,G2的平均值是M2

        d. 新的阈值T1=

        e. 如果T1与T不相等,则回到步骤b;如果相等,则T1就是最终的阈值

        灰度图片经过二值化后,效果如表1所示:

        3) 图片降噪

        由于验证码图片中有许多噪音,这会极大影响到后期的识别效果,我们需要对图片进行降噪处理,尽量保留图片中的字符信息,擦除噪音。图片降噪方法有很多,这里使用滑动窗口的方法来进行降噪处理。具体方法是:取图像中每个像素点的灰度值,将该值和其四周的八个像素点的值进行排序,取中值作为这个像素点的最终值。考虑到图片噪声一般都是相对的像素点,而字符区域一般是连成片的像素点,因此该方法可以去除孤立的噪音像素点。验证码图片的降噪效果如表3所示:

        4) 图片开运算

        为了便于对图片进行分割,需要对图片进行形态学处理。形态学处理表现为一种领域运算形式,通过一种特殊定义的被称为“结构单元”的领域,在每个像素位置上它与二值图像对应的区域进行特定的逻辑运算,逻辑运算的结果输出为图像对应的相应像素。为了使得字符轮廓平滑,抑制字符边界的小的噪点,我们使用了结构开变换。即对图像先腐蚀,再膨胀。

        在腐蚀操作中,定义A用B结构单元腐蚀,记作A⊙B,表示为:

        图片腐蚀实现java代码实现如下:

        /*腐蚀

        * @param source 输入图像灰度值的二维数组

        * @param threshold 当与运算结果值小于阈值时,图像点的值仍然设为0

        * sData 结构数组

        * @return 输出图像灰度值的二维数组*/

        private static int[][] correde(int[][] source,int threshold){

        int width=source[0].length;

        int height=source.length;

        int[][] result=new int[height][width];

        for(int i=0;i

        for(int j=0;j

        if(i>0&&j>0&&i

        int max =0;

        for(int k=0;k

        int x=k/3;

        int y=k%3;

        if(sData[k]!=0){

        if(source[i-1+x][j-1+y]>max){

        max=source[i-1+x][j-1+y]; }}}

        if(max

        result[i][j]=0;

        }else{

        result[i][j]=max; }

        }else{

        result[i][j]=source[i][j]; }}}

        return result; }

        在膨胀操作中,定义A用B结构单元扩张,记作A⊕B,表示为:

        A⊕B =

        图片膨胀实现java代码实现如下:

        /* 膨胀运算

        * @param source 输入图像灰度值的二维数组

        * @param shreshold 当灰度值大于阈值(小于阈值127)时并且结构元素为1(0)时,认为对应位置匹配上;

        * sData 结构数组

        * @return 输出图像灰度值的二维数组*/

        private static int[][] dilate(int[][] source,int threshold){

        int width=source[0].length;

        int height=source.length;

        int[][] result=new int[height][width];

        for(int i=0;i

        for(int j=0;j

        if(i>0&&j>0&&i

        int max =0;

        ///对结构元素进行遍历

        for(int k=0;k

        int x=k/3;

        int y=k%3;

        if(sData[k]!=0){

        ///不为0时,必须全部大于阈值,否则就设置为0并结束遍历 if(source[i-1+x][j-1+y]>=threshold){ if(source[i-1+x][j-1+y]>max){ max=source[i-1+x][j-1+y];

        }

        }else{

        ////与结构元素不匹配,赋值0,结束遍历

        max=0;

        break;

        }}}

        result[i][j]=max;

        }else{

        result[i][j]=source[i][j]; }}}

        return result; }

        在实践中,我们使用的结构体为一个3*3的矩阵:

        开运算效果如表4所示:

        3 字符分割与识别

        为了便于识别,需要将验证码图片进行分割,使得分割后的每个图片中只出现一个字符。由于待分析的验证码无字符粘连现象,故而我们使用比较简单的竖直投影法。假定背景色为白色(灰度值255),字符颜色为黑色(灰度值0),从左到右扫描图片的每列像素点,如果一列的灰度值总和小于阈值T,就认为这是字符列,如果小于阈值T,则认为这是间隔列。一次扫描之后,记录所有字符开始列和间隔开始列,并据此分割图片。

        在字符识别阶段,首先需要制作样本库,样本需要包含所有可能出现的字符。样本字符图片统一使用26*26像素的图片,背景色用0表示,字符色用1表示,也就是一个26*26的矩阵。对于待识别的字符图片,首先采用双线性差值算法,把图片变为26*26大小,采用同样的方法来获得图片对应的矩阵。在样本库中,使用汉明距离获得当前字符图片与样本库中各个图片的距离最近的一个图片,该图片所代表的值即是验证码对应字符的值。

        4 识别效果

        根据上述步骤,我们采用了java代码实现了算法,并对CSDN网站的1000张验证码图片进行了识别,总体识别率大约为60%,识别的难点主要出现在易于被混淆的字符上,例如字母O、D和数字0,字母Z和数字2等字符。

        5 总结与展望

        本文对验证码图片的识别做了深入研究,依次采用了图片灰度化、二值化、图片降噪、图片开运算等数字图像处理方法对验证码图片进行了预处理,使得识别效果有了显著的提高。下一步可以研究以下几个方面:1)改进字符识别算法,可以采用SVM算法或者基于神经网络的学习算法;2)解决字符粘连时的字符分割问题;3)提升图片降噪的效果。

        参考文献:

        [1] Simon Haykin.Neural networks: a comprehensive foundation[M].2nded.USA: Prentice Hall,1998:443-483.

        [2] 冈萨雷斯.数字图像处理[D].3版北京:电子工业出版社,2011.

        [3] 彭洪江.低照度图像的降噪算法与实现[D].武汉理工大学,2014 .

        [4] 陈绍林.车牌定位与字符分割算法的研究及实现[D].西安电子科技大学,2013.

        [5] Serge Belongie Jitendra Malik Jan Puzicha. Matching with Shape Contexts [M].2000.

        [6] 文晓阳,高能,夏鲁宁,等.高效的验证码识别技术与验证码分类思想[J].计算机工程, 2009(8):63.

        [7] 王璐.验证码识别技术研究[D].中国科学技术大学,2011.

        [8] 成洪静,陈立潮,张英俊,等.基于SVM的多分类器构造算法的研究[J].计算机技术与发展,2008 (12):109-112.

下载本文

显示全文
专题