验证码的识别和运用
验证码的主要目的是强制人机交互来抵御机器自动化攻击,为了确保服务器系统的稳定和用户信息的安全,越来越多的网站采用了验证码技术。图片验证码是目前最常用的一种,本文也主要讨论这种验证码的识别。最近在一个爬虫项目中遇到了验证码,需要机器自动识别绕过。这些验证码大都分辨率都较低,本身信息量不大。通常被加入一种或多种干扰因素:各种背景干扰,噪声点像素,字体形变和累叠,字符位置随机及个数不定,反色等情况。在网上调研了资料和文献后,分别采用OCR识别和模板库匹配方法对不同类型验证码进行了识别。主要过程可以分解为三个步骤:1.图片清理,2.字符切分,3.字符识别。以下结合工作经验和调研内容讲解一些常用的验证码识别方法和过程。1.图片清理图片清理是为接下来的机器学习或模板匹配阶段做准备的,指通过灰度化、二值化、干扰点清理等过程,得到比较干净的图片数据
验证码中的噪音点通常是用来增加破解难度的随机元素,它们可以是点、线、形状或其他非字母数字的图形。下面我会描述一个典型的带有噪音点的验证码的例子,并且解释一下这些噪音是如何被加入到验证码中的。
以上图片是一个对比图,展示了一个带噪音点的验证码与其干净版本的对比。左边的图片显示了包含扭曲的字母和数字的验证码,周围散布着随机的噪音点和线条。右边的图片则是同一验证码的干净版本,没有噪音点或线条,只有清晰的字母和数字可见。这有助于理解噪音点在验证码中的实际效果。
为了增加识别难度,验证码图像上添加了以下类型的噪音:
1.随机点噪音:在整个图像的背景上随机分布的小黑点或小白点,这些点的密度不均匀,有的地方密集,有的地方稀疏。
2.随机线条噪音:在图像中添加一些斜的、弯曲的或者直的细线,线条的颜色可能与字母相同或不同,但足以干扰识别。
3.扭曲和变形:字母本身可能经过扭曲处理,比如旋转、拉伸或压缩,使得字母的形状变得不规则。
4.背景干扰:可能有杂色的背景,或是背景图案,这增加了额外的识别难度。
5.模糊效果:整个图像或部分区域可能应用了模糊效果,使得字母边缘变得不清晰。
6.颜色变化:字母可能使用了渐变色,或者背景与字母之间的对比度较低,使得区分更加困难。
** 如何添加噪音**
在生成验证码时,噪音可以通过编程语言中的图形库来添加,如Python的PIL库或OpenCV库。例如,随机点噪音可以通过在循环中随机选择图像中的坐标并设置像素值来实现。线条噪音可以通过绘制随机角度和长度的线条来完成。扭曲和变形则可以通过图像变换函数实现,而模糊效果通常由图像卷积滤波器如高斯模糊来完成。
去除噪音
验证码噪音的去除通常涉及图像处理和机器学习技术,包括但不限于:
滤波:使用高斯滤波、中值滤波等技术减少随机点噪音。
二值化:通过阈值分割将图像转换为黑白,有助于去除背景噪音。
形态学操作:如膨胀和腐蚀,用于清理细小的噪音点。
连通组件分析:识别和分离图像中的独立字符。
深度学习:使用卷积神经网络(CNNs)等模型进行特征提取和分类,以识别验证码中的有效信息。
艾埃巨擘 www.ai9v.cn
该方法的优点是:原理简单直观;可以针对不同网站定制优化;对于扭曲的字母和数字识别率较高。缺点是:开发量大,需要定制开发;需要收集大量的字符图片库;字符变化很多的情况,匹配次数增加速度下降;对于字符有粘连的图片识别率低;5. 支持向量机 支持向量机通俗来讲是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解。实际应用上,往往遇到的是非线性可分得情况,因此通过核函数把低维向量映射到更高维空间,使得样本满足线性可分。 验证码识别问题实际上是其中单个字符识别问题,而在字符可穷举的情况下,比如只有英文字符和数字,单个字符识别问题其实是一个分类问题。一个英文字母或数字表示一类,而验证码中切分后得到的单个字符需要被机器自动分到某一类。一般情况下,把单个字符的灰度图片转成整形数组,数组的每一个元素表示图片的一个像素,即一个特征维度。我们切分得到的图片大小为10x16=160像素,即有160个特征,当特征数量多且特征之间关系不明确时,采用支持向量机分类比较合适。 LIBSVM 是台湾大学林智仁(Lin Chih-Jen)副教授等开发设计的一个简单、易于使用和快速有效的SVM模式识别与回归的软件包,他不但提供了编译好的可在Windows系统的执行文件,还提供了源代码,方便改进、修改以及在其它操作系统上应用。该软件还有一个特点,就是对SVM所涉及的参数调节相对比较少,提供了很多的默认参数,利用这些默认参数就可以解决很多问题;并且提供了交互检验(Cross Validation)的功能。主要参数使用:多类别(C-SVC=0),radial basis function(kernel_type=2),训练和预测代码如下。对于 这样轻微变形的验证码,有字母和数字共36个类别,收集训练样本共778个字符图的情况下,单字符预测准确率接近100%:
labels = [] samples = []for ch in captchaTemplate.keys(): for table in captchaTemplate[ch]: labels.append(ord(ch)) samples.append(map(lambda e:e/255., table)) problem = svm_problem(labels, samples) model = svm_train(problem, '-t 2 -c 500')print len(samples) data = map(lambda e:e/255., list(Image.open(TESTFILE).getdata(TESTFILE))) y = ord('z') prediction = svm_predict([y,], [data,], model)print prediction
该方法的优点是:无需设计快速的图像匹配算法;只要图片切分方法合适,对于扭曲倾斜的字母和数字识别率也较高;并且可以针对不同类型的验证码做定制优化。缺点是:支持向量机原理比较复杂,无法直观解释,需要了解支持向量机等机器学习方法。6. 神经网络 以上验证码识别都依赖于字符切分,切分的好坏几乎直接决定识别的准确程度。而对于有字符粘连的图片,往往识别率就会低很多。目前验证码识别最先进的是谷歌在识别“街景”图像中门牌号码中使用的一套的算法。该算法将定位、分割和识别等几个步骤统一起来,采用一种“深度卷积神经网络”(deep convolutional neural network)方法进行识别,准确率可以达到99%以上。谷歌拿自有的reCAPTCHA验证码做了测试,结果发现,对于难度最大的reCAPTCHA验证码,新算法的准确率都达到 99.8%,这可能也好于大多数人为验证。 验证码作为一种辅助安全手段在Web安全中有着特殊的地位,了解验证码识别的方法和原理,不仅有利于绕过验证码抓取网站内容,而且有利于设计更安全合理的验证码。