Python网站验证码识别


Posted in Python onJanuary 25, 2016

0x00 识别涉及技术

验证码识别涉及很多方面的内容。入手难度大,但是入手后,可拓展性又非常广泛,可玩性极强,成就感也很足。

验证码图像处理

验证码图像识别技术主要是操作图片内的像素点,通过对图片的像素点进行一系列的操作,最后输出验证码图像内的每个字符的文本矩阵。

读取图片
图片降噪
图片切割
图像文本输出

验证字符识别

验证码内的字符识别主要以机器学习的分类算法来完成,目前我所利用的字符识别的算法为KNN(K邻近算法)和SVM (支持向量机算法),后面我 会对这两个算法的适用场景进行详细描述。

获取字符矩阵
矩阵进入分类算法
输出结果

涉及的Python库

这次研究主要使用了以下这三个库

numpy(数学处理库)
Image(图像处理库)
ImageEnhance(图像处理库)

验证码识别技术难点

验证码识别由两部分组成,分别是验证码图片处理和验证码字符学习。

在编码过程中,我认为难度最大的部分是识别算法的学习和使用。
在写文档的时候,我认为难度最大的部分是图像处理部分,图像处理部分需要对抗各种干扰因素,对抗不同类型的验证码需要不同的算法支持,因此图像处理程序需要对各种验证码具体问题具体分析,不能抱有大而全的思想,务必注重细节处理。

0x01 学习与识别

验证码识别的过程分为学习过程与识别过程

学习

Python网站验证码识别

识别

Python网站验证码识别

Python网站验证码识别

上图代码运用的是SVM的识别过程

0x02 图像处理

验证码图像处理脑图

Python网站验证码识别

如上图所示,验证码图像处理模块是一个结构规整、内部分支复杂的模块,整个验证码识别准确率全靠这个模块,可谓是整个验证码识别的根本。如 上文所说,图像处理模块玩的是图片内的每一个像素百度百科:像素,因此这个模块好上手。

Python网站验证码识别

上面这两句便可以打开一个图像对象,im对象内置许多方法有兴趣可以查看Image库源码或者参考Python Imaging Library Handbook 图片增加对比度、锐化、调整亮度、二值化,这四块是比较规整的模块,处理调用库函数即可。下面主要说说图片降噪和清楚单像素干扰线。

图片清除噪点

图片降噪的原理是利用9宫格内信息点(信息像素,一般经过预处理的信息像素为黑色)。

Python网站验证码识别

上图黑色部分为(x,y),单像素噪点处理时分别验证周围的八个点是否为白色,如果为白色即可判断(x,y)为噪点。同理双像素噪点需要考虑两个像 素的排列是横向还是纵向或者是斜向,之后判断其周围10个像素是否均为白色像素即可。同理三像素噪点也是这样,我尝试的情况三像素噪点不包括 横向排列和纵向排列。

图片清除干扰线

对于单像素的干扰线目前可以解决,但是大宽度干扰线则会产生判断上的误差,目前不好解决。

Python网站验证码识别

上图的干扰线为单像素,因此通过算法即可解决。

Python网站验证码识别

干扰线处理后的图片如上图所示。

图片切割

对于去噪后的图片,我们需要对图片进行切割,切割的目的是为了提取信息,方便把图片中的数字转化为01形式的文本。 我所采用的切割方式是投影法.

Python网站验证码识别

如上图所示,对于切割数字3,首先需要找到垂线A和B,判断步骤是:纵向从左向右扫描图片,找到第一条含有信息点的直线记为A,继续向右扫描, 当从A开始,找到第一条无信息点的直线记为B,从投影的角度来看,A与B之间X轴上的投影的信息值均大于0,切割A与B之间的图像后,以新图像为 基础,找出C与D,至此便可切割出数字3。

图片切割目前可以仅可对非粘连字符进行切割,对于粘连字符,我的程序并没能很好的处理。

信息输出

当获取了切割好的图片,由于图片只有黑色与白色,因此遍历每一个像素点,根据像素点的颜色来进行0,1输出,一般认为黑色像素输出1,白色像素 输出0。

Python网站验证码识别

0x03 识别算法概述

字符识别算法整体流程很好理解,举个例子,字符像素文本A进入识别算法,通过对算法的结果进行判断,便可以完成识别过程。我实践了两种识别算 法,第一种是KNN算法,第二种是SVM算法,下面我将以个人的角度来阐述下这两种算法的原理以及适用场景,个人水平有限,算法细节可以参考我 之后给出的链接。

KNN(K邻近算法)

KNN算法是一种简单的算法,KNN算法基本思想是把数据转化为点,通过计算两点之间的距离来进行判断。 在n维度下,两点间距离可以表示为 S = math.sqrt((x1-y1)^2+(x2-y2)^2+.+(xn-yn)^2)。

SVM(支持向量机)

SVM算法相比较KNN算法来说,原理上要复杂复杂的多,SVM算法基本思想是把数据转化为点,通过把点映射到n维空间上,通过n-1维的超平面 切割,找到最佳切割超平面,通过判断点在超平面的哪一边,来判断点属于哪一类字符。

Python网站验证码识别

但是SVM算法的特点只能在两类中间比较,因此把字符识别运用到该算法上,还需要在比较过程中加以一个遍历算法,遍历算法可以减少大量无效计 算,遍历的场景是一个有向无环图。

算法细节文档链接

jerrylead 的blog : Machine Learning
支持向量机通俗导论(理解SVM的三层境界)

0x04 识别算法适用场景

KNN与SVM的适用场景存在一定区别。

KNN算法在运行过程上来说,并不存在学习过程,只是遍历已知分类进行距离上的判断,根据待测数据与已知分类进行比较,找出与待测距离最近的n个数据来进行匹配,因此当已分类的样本越来越多,KNN算法的运算时间会越来越长。

SVM算法在运行过程中,是存在学习的过程的,通过对已知分类标签进行两两组合,找出每个组合的切割方程。待测数据只需要一个一个计算切割方程,根据切割方程的返回值来判断下一个执行的是哪个方程即可。0-9数字的判断,只需要执行9次方程计算即可。SVM多类分类方法

因此如果大规模识别验证码,我建议适用SVM作为识别算法。

0x05 实践细节注意事项

这部分内容是我所遇到的问题。

规则化图像

当切割的验证码以数字呈现在文本里,他们的像素是各不相同的,需要把这些标准化,我选择标准化在27*30像素是一个经验值。此外,还需要把新图 像放置在标准化像素的正中央。

Python网站验证码识别

使用SVM构建超平面方程

SVM算法的重点是寻找切割方程,首先需要把待判断的两种元素存入到dataArr和labelArr中,通smoP方程寻找b和alphas。

Python网站验证码识别

利用方程组预测——遍历dag图

由于svm是二分类器,只能判断是或者不是,只需要使用k一1个决策函数即可得出结果,不存在误分、拒分区域;另外,由于其特殊的结构,故有一定的容错性,分类精度较一般的二叉树方法高。

对于0123456789 共10个字符 共有45种非重复组合。利用dag只需判断9次即可找出目标。

Python网站验证码识别

0x06 实践总结

运用机器学习算法时,如果不理解实现原理,先直接套接口,总之先实现功能,不必强求对算法的彻底理解。 2. 识别算法是通用的。

处理不同验证码,应该有不同的处理策略。

测试发现,主要耗时发生在构建方程过程中,构建方程耗时105s,识别1s。

图像去噪时对于大宽度的干扰线没有好的解决办法(干扰线宽度大于3像素)。 6. 图像切割在面临图像粘连时,目前无很好的处理方法。

Python 相关文章推荐
Python文件操作之合并文本文件内容示例代码
Sep 19 Python
python使用PyCharm进行远程开发和调试
Nov 02 Python
Python3.7中安装openCV库的方法
Jul 11 Python
Python BeautifulSoup [解决方法] TypeError: list indices must be integers or slices, not str
Aug 07 Python
pytorch 指定gpu训练与多gpu并行训练示例
Dec 31 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
利用 Python ElementTree 生成 xml的实例
Mar 06 Python
基于Python3.7.1无法导入Numpy的解决方式
Mar 09 Python
PyQt5实现登录页面
May 30 Python
linux mint中搜狗输入法导致pycharm卡死的问题
Oct 28 Python
给numpy.array增加维度的超简单方法
Jun 02 Python
使用python创建股票的时间序列可视化分析
Mar 03 Python
谈谈Python进行验证码识别的一些想法
Jan 25 #Python
基于Python Shell获取hostname和fqdn释疑
Jan 25 #Python
21行Python代码实现拼写检查器
Jan 25 #Python
Python字符串、元组、列表、字典互相转换的方法
Jan 23 #Python
Python随手笔记第一篇(2)之初识列表和元组
Jan 23 #Python
Python爬虫模拟登录带验证码网站
Jan 22 #Python
Fiddler如何抓取手机APP数据包
Jan 22 #Python
You might like
用PHP制作静态网站的模板框架(一)
2006/10/09 PHP
PHP imagegrabscreen和imagegrabwindow(截取网站缩略图)的实例代码
2013/11/07 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
2014/06/22 PHP
destoon文章模块调用企业会员资料的方法
2014/08/22 PHP
Drupal简体中文语言包安装教程
2014/09/27 PHP
php实现parent调用父类的构造方法与被覆写的方法
2015/02/11 PHP
php计算整个目录大小的方法
2015/06/01 PHP
详解PHP+AJAX无刷新分页实现方法
2015/11/03 PHP
thinkPHP的表达式查询用法详解
2016/09/14 PHP
PHP基于双向链表与排序操作实现的会员排名功能示例
2017/12/26 PHP
PHP后期静态绑定之self::限制实例分析
2018/12/21 PHP
JS小功能(列表页面隔行变色)简单实现
2013/11/28 Javascript
javascript生成大小写字母
2015/07/03 Javascript
jQuery提示插件qTip2用法分析(支持ajax及多种样式)
2016/06/08 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
2016/11/03 Javascript
JS异步加载的三种实现方式
2017/03/16 Javascript
微信小程序实现点击图片旋转180度并且弹出下拉列表
2018/11/27 Javascript
微信小程序实现原生步骤条
2019/07/25 Javascript
Vant picker 多级联动操作
2020/11/02 Javascript
[04:09]显微镜下的DOTA2第十二期—NaVi美如画的团战
2014/06/23 DOTA
python cx_Oracle的基础使用方法(连接和增删改查)
2017/11/19 Python
python编写暴力破解zip文档程序的实例讲解
2018/04/24 Python
Python实现抓取HTML网页并以PDF文件形式保存的方法
2018/05/08 Python
详解python算法之冒泡排序
2019/03/05 Python
用Pytorch训练CNN(数据集MNIST,使用GPU的方法)
2019/08/19 Python
python聚类算法解决方案(rest接口/mpp数据库/json数据/下载图片及数据)
2019/08/28 Python
基于python3 的百度图片下载器的实现代码
2019/11/05 Python
对python中 math模块下 atan 和 atan2的区别详解
2020/01/17 Python
Python3 requests模块如何模仿浏览器及代理
2020/06/15 Python
把Anaconda中的环境导入到Pycharm里面的方法步骤
2020/10/30 Python
CSS图片翻转动画技术详解(IE也实现了)
2014/04/03 HTML / CSS
台湾旅游网站:雄狮旅游网
2017/08/16 全球购物
小学后勤管理制度
2014/01/14 职场文书
财务部经理岗位职责
2014/02/03 职场文书
八项规定整改方案
2014/10/01 职场文书
2015年护士节慰问信
2015/03/23 职场文书