1、背景
验证码自动识别在模拟登陆上使用的较为广泛,一直有耳闻好多人在使用机器学习来识别验证码,最近因为刚好接触这方面的知识,所以特定研究了一番。发现网上已有很多基于machine learning的验证码识别,本文主要参考几位大牛的研究成果,集合自己的需求,进行改进、学习。
2、基本工具
开发环境:
python 3.5 + pycharm
模块:
Pillow、sklearn、numpy及其他子模块
3、基本流程
描述整个识别流程:
①验证码清理并生成训练集样本
②验证码特征提取
③拟合识别模型
④识别模型测试
4、关于数据集
没有特意网上找python的生成脚本,用了一个java的验证码生成脚本。验证码是数字+大写字母+小写字母的组合,即[0-9]+[A-Z]+[a-z]。文件名是验证码的正确数字标签,实例如下
使用三个数据集:
①训练集(training set):10000张验证码
②测试集(test set):100张验证码
③验证集(validation set):100张验证码
5、验证码清理并生成训练集样本
(1)读取图片
首先读取该文件路径下的所有图片文件名称,并逐张打开。返回结果image_array,每一个元素类型为“”。
def read_captcha(path):
image_array = []
image_label = []
file_list = os.listdir(path) # 获取captcha文件
for file in file_list:
image = Image.open(path + '/' + file) # 打开图片
file_name = file.split(".")[0] #获取文件名,此为图片标签
image_array.append(image)
image_label.append(file_name)
return image_array, image_label
(2)图像粗清理
图像粗清理包括以下步骤:
step 1:原始图像是RGB图像,即维度为 (26, 80, 3)。将其转换为灰度图像,维度变为(26, 80)。
原始图像:
灰度图像:
step 2:对于将要识别的验证码,显然,里面出现了很多用于干扰作用的灰色线条。博主通过设定灰度阈值(默认100),对图像中大于阈值的像素,赋值为255(灰度图像中像素值范围是0~255,其中255是白色,0是黑色)。发现对于此类型的验证码,这种方法很实用有木有。
defimage_transfer(image_arry):""":param image_arry:图像list,每个元素为一副图像
:return: image_clean:清理过后的图像list"""image_clean=[]for i, image inenumerate(image_arry):
image= image.convert('L') #转换为灰度图像,即RGB通道从3变为1
im2 = Image.new("L", image.size, 255)for y in range(image.size[1]): #遍历所有像素,将灰度超过阈值的像素转变为255(白)
for x inrange(image.size[0]):
pix=image.getpixel((x, y))if int(pix) > threshold_grey: #灰度阈值
im2.putpixel((x, y), 255)else:
im2.putpixel((x, y), pix)
image_clean.append(im2)return image_clean
(3)图像细清理
仅仅通过粗清理的办法,无法完全去除所有噪声点。此处引入