背景简介
最近开始接触业务安全,说到业务安全就不得不提薅羊毛了,而薅羊毛的人手里一定都有图片验证码的识别工具,所以想研究一下图片验证码的识别,本文使用python实现了一个图片验证码识别工具,可以通过提高训练样本的数量不断提高识别准确率。现在只能识别一些简单的图片验证码,如果想识别复杂度更高的验证码,可以在此基础上优化图片预处理的模块。本文最后会附上完整代码供大家参考交流。
使用工具
- Python
- PIL:图片处理库
- Libsvm : python实现的支持向量机SVM
原理
验证码识别主要分成三部分:预处理,字符分割,字符识别。 QQ图片20180808144134.jpg字符分割的时候提供一个质量较好的图片。(本文由于使用的图片验证码较简单,预处理只需做色度空间转换,即灰度化及二值化)
字符分割:得到经过预处理的图片后需要将每个字符单独分隔出来。
字符识别:本文利用libsvm,收集训练样本,生成识别模型,再利用识别模型来识别图片验证码。
基本流程
一、训练样本生成识别模型文件
1. 获取样本图片验证码
2. 图片处理:灰度化,二值化,切割成4张有序的单字符图片
3. 人工识别每张切割好的图片,按数字放在不同的数字目录中
4. 提取每张切割图片的特征生成特征文件
5. 训练特征文件中的数据集生成识别模型文件
二、识别图片验证码
1. 获取样本图片验证码
2. 图片处理:灰度化,二值化,切割成4张有序的单字符图片
3. 提取每张切割图片的特征生成特征文件
4. 利用识别模型文件和生成的特征文件识别图片验证码
具体实现
一、训练样本生成识别模型文件
1. 获取样本图片验证码
根据验证码url获取图片保存到文件夹中,代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具!可以使用多线程获取验证码,代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具!2. 图片处理:灰度化,二值化,切割成4张单字符图片
利用PIL来实现图片的灰度化和二值化:
灰度化结果如下:
当年为了褥羊毛做的post,python验证码智能识别工具!二值化结果如下:
当年为了褥羊毛做的post,python验证码智能识别工具!之后对图片进行切割,切割的方式很简单,图片有横轴x和纵轴y,首先进行纵向切割,遍历出所有存在黑色像素点的列,以此来确定要切割的x值。再对每个数字进行横向切割,遍历出所有存在黑色像素点的行,以此来确定要切割的y值。切割的效果如下图:
当年为了褥羊毛做的post,python验证码智能识别工具!代码实现如下:
当年为了褥羊毛做的post,python验证码智能识别工具!3. 人工识别每张切割好的图片,按数字放在不同的数字目录中
本文收集的样本较少,每个数字只使用15张样本。
当年为了褥羊毛做的post,python验证码智能识别工具! 当年为了褥羊毛做的post,python验证码智能识别工具!4. 提取每张切割后的图片的特征生成特征文件
针对每张图片,我们将每行上的黑色像素点个数和每列上的黑色像素点个数作为特征生成特征文件。这个特征文件按照libsvm指定的格式生成一组带特征值和标记值的向量文件,如下图:
当年为了褥羊毛做的post,python验证码智能识别工具!格式说明:
[label] [index1]:[value1][index2]:[value2] ...
[label] [index1]:[value1] [index2]:[value2] ...
第一列label是标签列,就是图片对应的人工标记的数字(0到9)。后面的列是一组组的特征值,冒号前面是有顺序的索引index,通常是放连续的整数,冒号后面是用来训练的数据(即黑色像素的个数)。
实现代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具!5. 训练特征文件中的数据集生成识别模型文件
使用libsvm生成识别模型文件,代码如下:
os.system('C:Python27Libsite-packageslibsvm-3.21windowssvm-scale.exe -l -1 -u 1 E:mode.txt>E:mode_scale.txt') #将特征文件中的值进行尺寸变换
y, x = svmutil.svm_read_problem('E:mode_scale.txt')
m = svmutil.svm_train(y,x,'-c 0.5 -g 0.015625') #c 和 g 的最佳参数值可通过调用findparam()获得
svmutil.svm_save_model('E:svm_mode_file', m) #生成最终的模型文件
其中使用svm-scale.exe对特征文件进行尺度变换,来提高预测正确率, 因为原始数据可能范围过大或过小 , svm-scale.exe可以先将数据重新 scale ( 缩放 ) 到适当范围。并且训练的时候可以指定一些参数,来提高识别的准确率。其中最重要的两个参数是c和g,这两个参数可以利用libsvm提供的grid脚本来自动寻找最佳值。代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具! 当年为了褥羊毛做的post,python验证码智能识别工具! 当年为了褥羊毛做的post,python验证码智能识别工具!def findparam(): #寻找最佳参数
rate,param = grid.find_parameters('E:mode.txt', '-log2c -8,8,1 -log2g -8,8,1 -svmtrain C:Python27Libsite-packageslibsvm-3.21windowssvm-train.exe')
print('rate: ',rate)
print('param: ',param)
二、识别图片验证码
1,2 两步与训练模型的1,2两步一样,第3步是生成特征文件,此时由于没有人工识别label,所以在label处都标为0,并且也要使用svm-scale.exe对特征文件进行尺度变换,代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具!最后第4步,利用识别模型和特征文件识别图片验证码。代码如下:
当年为了褥羊毛做的post,python验证码智能识别工具!识别结果如下图:
当年为了褥羊毛做的post,python验证码智能识别工具!后期可改进
- 针对复杂的图片验证码,增加对图片的去干扰,降噪等处理。
- 对图片的切割可以使用更优化的算法。
- 收集有英文字母的验证码,生成英文字母及数字的识别模型文件。
- 图片验证码识别过程耗时很少,主要的耗时在请求图片验证码url时。
完整代码
当年为了褥羊毛做的post,python验证码智能识别工具!
网友评论