本篇文章将实现一个识别验证码的案例。
基本思路及步骤:
1.先写一个关于验证码生成器的代码,得到一个有关验证码的库
2.对验证码库中的验证码图片进行处理并对其分割
3.训练数据,得到模型
4.对未知的验证码图片进行预测

由于目前的验证码的形式比较多样,但是验证的思路都是类似的,因此就先从简单的数字开始进行识别。我们先需要写一个验证码生成器,生成验证码库。
验证码需要有5个数字,并且有不同的颜色,还要再图片上加一些噪点和一些随机的线。
代码如下:

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
import randomdef getRandomColor():"""获取一个随机颜色(r,g,b)格式的:return:"""c1 = random.randint(0, 255)c2 = random.randint(0, 255)c3 = random.randint(0, 255)if c1 == 255:c1 = 0if c2 == 255:c2 = 0if c3 == 255:c3 = 0return(c1, c2, c3)def getRandomStr():"""获取一个随机数字,每个数字的颜色也是随机的:return:"""random_num = str(random.randint(0, 9))return random_numdef generate_captcha():# 获取一个Image对象,参数分别是RGB模式。宽150,高30, 随机颜色image = Image.new('RGB', (150, 50), (255,255,255))# 获取一个画笔对象,将图片对象传过去draw = ImageDraw.Draw(image)# 获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小font = ImageFont.truetype("ARLRDBD.TTF", size=32)label = ""for i in range(5):random_char = getRandomStr()label += random_char# 在图片上写东西,参数是:定位,字符串,颜色,字体draw.text((10+i*30, 0), random_char, getRandomColor(), font=font)# 噪点噪线width = 150height = 30# 画线for i in range(3):x1 = random.randint(0, width)x2 = random.randint(0, width)y1 = random.randint(0, height)y2 = random.randint(0, height)draw.line((x1, y1, x2, y2), fill=(0, 0, 0))# 画点for i in range(5):draw.point([random.randint(0, width), random.randint(0, height)], fill=getRandomColor())x = random.randint(0, width)y = random.randint(0, height)draw.arc((x, y, x + 4, y + 4), 0, 90, fill=(0, 0, 0))# 保存到硬盘,名为test.png格式为png的图片image.save(open(''.join(['captcha_images/', label, '.png']), 'wb'), 'png')# image.save(open(''.join(['captcha_predict/', label, '.png']), 'wb'), 'png')
if __name__ == '__main__':for i in range(150):generate_captcha()

运行程序之后生成150个验证码图片,会将验证码保存到文件夹中,相当于一个库,如下:




生成验证码之后,我们需要对验证码图片进行处理,具体处理的步骤如下:
1.对验证码图片二值化,首先把图像从RGB 三通道转化成Gray单通道,然后把灰度图(0~255)转化成二值图(0,1)。
2.对二值化验证码图片进行降噪处理,把干扰的点和线去掉
3.对处理后的验证码图片进行分割,根据像素格,把图片中的所有(5个)数字,分别保存到对应的0~9文件夹下。

具体代码如下:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import osdef binarization(path):img = Image.open(path)img_gray = img.convert('L')img_gray = np.array(img_gray)w, h = img_gray.shapefor x in range(w):for y in range(h):gray = img_gray[x, y]if gray <= 220:img_gray[x, y] = 0else:img_gray[x, y] = 1return img_gray# plt.figure('')# plt.imshow(img_gray, cmap='gray')# plt.axis('off')# plt.show()def noiseReduction(img_gray, label):height, width = img_gray.shapefor x in range(height-1):for y in range(width-1):cnt = 0if img_gray[x, y] == 1:continueelse:for i in [-1, 0, 1]:n = xn += iif n < 0:n = 0for j in [-1, 0, 1]:m = ym += jif m < 0:m = 0if img_gray[n, m] == 0:cnt += 1if cnt <= 4:img_gray[x, y] = 1plt.figure('')plt.imshow(img_gray, cmap='gray')plt.axis('off')plt.savefig(''.join(['clean_captcha_img/', label, '.png']))def img_2_clean():captchas = os.listdir(''.join(['captcha_images/']))for captcha in captchas:label = captcha.split('.')[0]img_path = ''.join(['captcha_images/', captcha])im = binarization(img_path)noiseReduction(im, label)def cutImg(label):labels = list(label)img = Image.open(''.join(['clean_captcha_img/', label, '.png']))for i in range(5):pic = img.crop((100*(1+i), 170, 100*(1+i)+100, 280))plt.imshow(pic)seq = get_save_seq(label[i])pic.save(''.join(['cut_number/', str(label[i]), '/', str(seq), '.png']))def get_save_seq(num):numlist = os.listdir(''.join(['cut_number/', num, '/']))if len(numlist) == 0 or numlist is None:return 0else:max_file = 0for file in numlist:if int(file.split('.')[0]) > max_file:max_file = int(file.split('.')[0])return int(max_file)+1def create_dir():for i in range(10):os.makedirs(''.join(['cut_number/', str(i)]))def clean2cut():clean_img = os.listdir(''.join(['clean_captcha_img/']))for img in clean_img:label = img.split('.')[0]cutImg(label)if __name__ == '__main__':img_2_clean()create_dir()clean2cut()

二值化并且降噪后的图片如下:

切割后的图片会保存在对应的数字文件夹中,

比如切割后的数字 6 如下:


1.把数据带入逻辑回归进行建模

(1)把切割好的数据,按照x(二位数组),y(一维数组)的方式传入logisticRegression.fit()函数进行拟合
我们可以通过网格搜索(GridSearch)来进行调参
(2)通过joblib包,把模型保存到本地

2.得到模型后,进行图像验证
(1)根据之前处理图像的步骤,重复操作新的图像
(2)对切割好的每个图像,独立的进行预测
(3)把最后预测结果进行拼接

注意在代码中需要导入之前写的函数,
代码如下:

import os
from PIL import Image
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.externals import joblib
from CAPTCHA.captcha_logistic import *def load_data():# 假设20*5像素块构成 20*5 = 100# [[11...1111]#  [111...111]#  ....#  [11111111]]# X = [[11111.....11111]] 100位 Y = [0]X, Y = [], []cut_list = os.listdir('cut_number')for numC in cut_list:num_list_dir = ''.join(['cut_number/', str(numC), '/'])nums_dir = os.listdir(num_list_dir)for num_file in nums_dir:img = Image.open(''.join(['cut_number/', str(numC), '/', num_file]))img_gray = img.convert('L')img_array = np.array(img_gray)w, h = img_array.shapefor x in range(w):for y in range(h):gray = img_array[x, y]if gray <= 240:img_array[x, y] = 0else:img_array[x, y] = 1img_re = img_array.reshape(1, -1)X.append(img_re[0])Y.append(int(numC))return np.array(X), np.array(Y)def generate_model(X, Y):X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3)log_clf = LogisticRegression(multi_class='ovr', solver='sag', max_iter=10000)# 利用交叉验证选择参数# param_grid = {"tol": [1e-4, 1e-3, 1e-2],#               "C": [0.4, 0.6, 0.8]}# grid_search = GridSearchCV(log_clf, param_grid=param_grid, cv=3)# grid_search.fit(X_train, Y_train)log_clf.fit(X_train, Y_train)# 将模型持久化joblib.dump(log_clf, 'captcha_model/captcha_model.model')def get_model():model = joblib.load('captcha_model/captcha_model.model')return modeldef capthca_predict():path = 'captcha_predict/unknown.png'pre_img_gray = binarizaion(path)noiseReduction(pre_img_gray, 'unknown')# cut imagelabels = ['0', '1', '2', '3', '4']img = Image.open(''.join(['clean_captcha_img/unknown.png']))for i in range(5):pic = img.crop((100*(1+i), 170, 100*(1+i)+100, 280))plt.imshow(pic)pic.save(''.join(['captcha_predict/', labels[i], '.png']))result = ''model = get_model()for i in range(5):path = ''.join(['captcha_predict/', labels[i], '.png'])img = Image.open(path)img_gray = img.convert('L')img_array = np.array(img_gray)w, h = img_array.shapefor x in range(w):for y in range(h):gray = img_array[x, y]if gray <= 220:img_array[x, y] = 0else:img_array[x, y] = 1img_re = img_array.reshape(1, -1)X = img_re[0]y_pre = model.predict([X])result = ''.join([result, str(y_pre[0])])return resultif __name__ == '__main__':X, Y = load_data()generate_model(X, Y)model = get_model()result = capthca_predict()print(result)

将要预测识别的验证码图片:

最终识别结果:

可以看到对给出的验证码图片进行了成功识别。

机器学习项目案例 简单的数字验证码自动识别相关推荐

  1. VB简单的数字验证码

    VB简单的数字验证码 工程包下载地址:https://download.csdn.net/download/ty5858/15095172

  2. 机器学习入门案例简单理解——Tensorflow之MNIST解析

    深度学习简单介绍 首先要简单区别几个概念:人工智能,机器学习,深度学习,神经网络.这几个词应该是出现的最为频繁的,但是他们有什么区别呢? 人工智能:人类通过直觉可以解决的问题,如:自然语言理解,图像识 ...

  3. 音频转换通项目案例简单过程分享

    文章目录 音频通转换 1.要求 2.BUG分享 3.问题 4.总结 5.二轮测试 6.音屏转换通项目收获 音频通转换 1.要求 测试音频转换通软件,采用尽可能的测试方法去测试软件,找出更多的缺陷 不少 ...

  4. 按键精灵+大漠插件简单数字验证码识别实践笔记

    因为资源短缺,公司用了一个很老的系统分配资源,每个项目每天都要经历上演一次像抢火车票一样的经历,而往往又空手而归,搞得大家疲惫不堪.而其中的关键在于几个简单的数字验证码的识别,于是在业余时间看了一些验 ...

  5. 基于CNN的四位数字验证码识别

    前言 验证码技术作为一种反自动化技术,使得很多程序的自动化工作止步.今天作者采用一些数字图像处理和CNN方法来识别较为简单的数字验证码 实验步骤 实验步骤主要围绕以下展开 图像预处理即滤除噪声和字符分 ...

  6. 【验证码识别】基于遗传算法优化OUST结合BP神经网络实现数字验证码识别含Matlab源码

    1 简介 本项目基于MATLAB完成数字验证码识别的GUI设计,图像处理,验证码生成.识别等功能.采用BP神经网络来实现对验证码图像的识别.验证码的识别,大概分为图片预处理.分割字符.识别字符三个过程 ...

  7. (第42册)Python项目案例开发从入门到实战——爬虫、游戏和机器学习(第2版) 夏敏捷 郑秋生 尚展垒著

    本书由Python基础开发入手,延伸至爬虫技术开发.游戏开发.人工智能开发.网络应用开发.图像处理和可视化开发6个Python经典开发方向: 全书共提供25个项目案例,以项目驱动方式展开各知识点的讲解 ...

  8. python智慧城市_智慧城市背景下Python机器学习项目实战案例分享

    首先,何为智慧城市?智慧城市的"智慧"源自何处? 智慧城市的特征在于运用大数据和数字技术提高居民生活质量. 机构获得的数据越全面.越实时,它们就越有能力观测事件发生的详情.分析需求 ...

  9. 智慧城市背景下Python机器学习项目实战案例分享

    首先,何为智慧城市?智慧城市的"智慧"源自何处? 智慧城市的特征在于运用大数据和数字技术提高居民生活质量. 机构获得的数据越全面.越实时,它们就越有能力观测事件发生的详情.分析需求 ...

最新文章

  1. Puppet学习之文件管理
  2. The database returned no natively generated identity value错误解决方案
  3. 程序员都和谁一起睡觉?
  4. html网页共用头部和脚部,如何在HTML不同的页面中,共用头部与尾部?_html/css_WEB-ITnose...
  5. python script文件夹在哪_Python获取当前脚本文件夹(Script)的绝对路径方法代码
  6. 利用tabluea分析数据的案例_利用德温特分析Dartsip的案例检索结果
  7. 数据结构-第九章 内部排序-知识点总结1
  8. 求余和取模的计算公式
  9. Java高级语法笔记-抽象类
  10. 成员/方法/属性/私有
  11. Spring Boot 学习系列(07)—properties文件读取
  12. datagrid java_Easyui Datagrid增删改及后台交互(java)
  13. 利用MFC向导生成单文档应用程序框架
  14. vs2008+sp1
  15. OpenGL基础4:最基础的单元 —— 三角形
  16. shell中日期操作
  17. 处理MySql连接超时引起的错误
  18. PHP搭建IDC网站,SWAPIDC系统完整移除云平台修改版 个人搭建idc空间商网站平台
  19. 软件工程-基本流程图
  20. GraphicsLab Project之简易贴画系统(Decal System)

热门文章

  1. 港科夜闻|香港科技大学(广州)拟获批首个省级重点实验室
  2. 用python写猜数字游戏
  3. 手机QQ浏览器的HTML管理器,手机qq浏览器中文件管理器有哪些功能
  4. Windows 7、8、8.1安装.NET 3.5报错问题
  5. win7 凭据管理无法保存
  6. 如本科技上海分公司乔迁新址,加速长三角地区的业务覆盖
  7. 基于自适应反向学习的黏菌算法
  8. Vertica的那些事
  9. java8判断当前时间是否大于某个时间
  10. yum 源没有php7.0,yum安装最新版php7的操作方法