当前位置: 首页 > news >正文

基于字符的图片验证码识别算法的设计与实现

基于字符的图片验证码识别算法的设计与实现

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

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

                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.


http://www.mrgr.cn/news/63245.html

相关文章:

  • 什么?一级造价师考试是“纸老虎”?
  • Harmony OS搭建广告展示页
  • elcipse工具使用记录
  • 数据库编程 SQLITE3 Linux环境
  • Webserver(2.3)exec函数族
  • Python bs4 结合 Scrapy,进行数据爬取和处理
  • springcloud通过MDC实现分布式链路追踪
  • 九识智能与徐工汽车达成战略合作,共绘商用车未来新蓝图
  • SAP ABAP开发学习——BADI增强操作步骤示例2
  • 在阿里云快速启动Umami玩转网页分析
  • 一位专科生面上网络安全的经验总结_网络安全专科
  • 视频批量裁剪工具
  • 探索智能投顾:正大金融数据分析如何优化市场策略
  • 【自动化测试】APP UI 自动化(安卓手机)-本地环境搭建
  • SSID,即Service Set Identifier(服务设置的表示符号)
  • CBAM填报攻略:关键点解析与实操案例分享
  • 台式电脑如何改ip地址:全面解析与实操指南
  • 成功解决:notepad++搜索结果窗口不见了,怎么找回?
  • 【无人机设计与控制】四旋翼无人机飞行姿态(ADRC)自抗扰控制Matlab仿真
  • msys2更换国内源(多个文件(不是3个文件的版本!))
  • 2024年重磅综述:探索深度多模态数据融合的学术前沿动态!
  • STM32滴答时钟是否每次计时1ms都要中断一下,更新ms数
  • 【测试工具篇一】全网最强保姆级教程抓包工具Fiddler(1)
  • VB中的日志记录(Logging)机制及其重要性
  • Vatee万腾平台:企业数字化之旅的全能助手与伙伴
  • FemtoMega阵列同步采集示例