python验证码识别的示例代码
作者:Hi!Roy! 发布时间:2023-08-04 03:20:24
写爬虫有一个绕不过去的问题就是验证码,现在验证码分类大概有4种:
图像类
滑动类
点击类
语音类
今天先来看看图像类,这类验证码大多是数字、字母的组合,国内也有使用汉字的。在这个基础上增加噪点、干扰线、变形、重叠、不同字体颜色等方法来增加识别难度。
相应的,验证码识别大体可以分为下面几个步骤:
灰度处理
增加对比度(可选)
二值化
降噪
倾斜校正分割字符
建立训练库
识别
由于是实验性质的,文中用到的验证码均为程序生成而不是批量下载真实的网站验证码,这样做的好处就是可以有大量的知道明确结果的数据集。
当需要真实环境下需要获取数据时,可以使用结合各个大码平台来建立数据集进行训练。
生成验证码这里我使用Claptcha这个库,当然Captcha这个库也是个不错的选择。
为了生成最简单的纯数字、无干扰的验证码,首先需要将claptcha.py的285行_drawLine做一些修改,我直接让这个函数返回None,然后开始生成验证码:
from claptcha import Claptcha
c = Claptcha("8069","/usr/share/fonts/truetype/freefont/FreeMono.ttf")
t,_ = c.write('1.png')
这里需要注意ubuntu的字体路径,也可以在网上下载其他字体使用。生成验证码如下:
可以看出,验证码有形变。对于这类最简单的验证码,可以直接使用谷歌开源的tesserocr来识别。
首先安装:
apt-get install tesseract-ocr libtesseract-dev libleptonica-dev
pip install tesserocr
然后开始识别:
from PIL import Image
import tesserocr
p1 = Image.open('1.png')
tesserocr.image_to_text(p1)
'8069\n\n'
可以看出,对于这种简单的验证码,基本什么都不做识别率就已经很高了。有兴趣的小伙伴可以用更多的数据来测试,这里我就不展开了。
接下来,在验证码背景添加噪点来看看:
c = Claptcha("8069","/usr/share/fonts/truetype/freefont/FreeMono.ttf",noise=0.4)
t,_ = c.write('2.png')
生成验证码如下:
识别:
p2 = Image.open('2.png')
tesserocr.image_to_text(p2)
'8069\n\n'
效果还可以。接下来生成一个字母数字组合的:
c2 = Claptcha("A4oO0zZ2","/usr/share/fonts/truetype/freefont/FreeMono.ttf")
t,_ = c2.write('3.png')
生成验证码如下:
第3个为小写字母o,第4个为大写字母O,第5个为数字0,第6个为小写字母z,第7个为大写字母Z,最后一个是数字2。人眼已经跪了有木有!但现在一般验证码对大小写是不做严格区分的,看自动识别什么样吧:
p3 = Image.open('3.png')
tesserocr.image_to_text(p3)
'AMOOZW\n\n'
人眼都跪的计算机当然也废了。但是,对于一些干扰小、形变不严重的,使用tesserocr还是十分简单方便的。然后将修改的claptcha.py的285行_drawLine还原,看添加干扰线的情况。
p4 = Image.open('4.png')
tesserocr.image_to_text(p4)
加了条干扰线就完全识别不出来了,那么有没有什么办法去除干扰线呢?
虽然图片看上去是黑白的,但还需要进行灰度处理,否则使用load()函数得到的是某个像素点的RGB元组而不是单一值了。处理如下:
def binarizing(img,threshold):
"""传入image对象进行灰度、二值处理"""
img = img.convert("L") # 转灰度
pixdata = img.load()
w, h = img.size
# 遍历所有像素,大于阈值的为黑色
for y in range(h):
for x in range(w):
if pixdata[x, y] < threshold:
pixdata[x, y] = 0
else:
pixdata[x, y] = 255
return img
处理后的图片如下:
可以看出处理后图片锐化了很多,接下来尝试去除干扰线,常见的4邻域、8邻域算法。所谓的X邻域算法,可以参考手机九宫格输入法,按键5为要判断的像素点,4邻域就是判断上下左右,8邻域就是判断周围8个像素点。如果这4或8个点中255的个数大于某个阈值则判断这个点为噪音,阈值可以根据实际情况修改。
def depoint(img):
"""传入二值化后的图片进行降噪"""
pixdata = img.load()
w,h = img.size
for y in range(1,h-1):
for x in range(1,w-1):
count = 0
if pixdata[x,y-1] > 245:#上
count = count + 1
if pixdata[x,y+1] > 245:#下
count = count + 1
if pixdata[x-1,y] > 245:#左
count = count + 1
if pixdata[x+1,y] > 245:#右
count = count + 1
if pixdata[x-1,y-1] > 245:#左上
count = count + 1
if pixdata[x-1,y+1] > 245:#左下
count = count + 1
if pixdata[x+1,y-1] > 245:#右上
count = count + 1
if pixdata[x+1,y+1] > 245:#右下
count = count + 1
if count > 4:
pixdata[x,y] = 255
return img
处理后的图片如下:
好像……根本没卵用啊?!确实是这样的,因为示例中的图片干扰线的宽度和数字是一样的。对于干扰线和数据像素不同的,比如Captcha生成的验证码:
从左到右依次是原图、二值化、去除干扰线的情况,总体降噪的效果还是比较明显的。另外降噪可以多次执行,比如我对上面的降噪后结果再进行依次降噪,可以得到下面的效果:
再进行识别得到了结果:
p7 = Image.open('7.png')
tesserocr.image_to_text(p7)
'8069 ,,\n\n'
另外,从图片来看,实际数据颜色明显和噪点干扰线不同,根据这一点可以直接把噪点全部去除,这里就不展开说了。
第一篇文章,先记录如何将图片进行灰度处理、二值化、降噪,并结合tesserocr来识别简单的验证码,剩下的部分在下一篇文章中和大家一起分享。
来源:http://www.hi-roy.com/2017/09/19/Python%E9%AA%8C%E8%AF%81%E7%A0%81%E8%AF%86%E5%88%AB/?utm_source=tuicool&utm_medium=referral


猜你喜欢
- 安装好所需要的插件和包:python、django、pip等版本如下:采用Django REST框架3.01、在python文件夹下D:\p
- 1. 时间差函数(TIMESTAMPDIFF、DATEDIFF)需要用MySQL计算时间差,使用TIMESTAMPDIFF、DATEDIFF
- 在默认情况下,MySQL搜索不区分大小写(但某些字符集始终区分大小写,如czech)。这意味着,如果你使用col_name LIKE
- 在Oracle 8i版本之前,使用internal用户来执行数据库的启动和关闭以及create database等操作;从8i版本以后,Or
- 速查表是帮你记住东西的有效工具。Web设计师和开发者经常使用的快捷键简表会使他们在网上的工作效率大大提高。事实上,速查表就是来帮助我们把日常
- django是python语言快速实现web服务的大杀器,其开发效率可以非常的高!但因为秉承了语言的灵活性,django框架又太灵活,以至于
- 很多书籍里面讲的Python备份都是在linux下的,而在xp上测试一下也可以执行备份功能,代码都差不多相同,就是到执行打包的时候是不一样的
- 安装redis并启动下载地址,选择Stable版本下载或者本地下载地址:https://www.jb51.net/softs/504128.
- 目录一、数据库引擎1.1 查看数据库引擎1.2 修改默认数据库引擎二、数据库字符集2.1 查看字符集2.2 修改字符集一、数据库引擎1.1
- 爬取某人的微博数据,把某人所有时间段的微博数据都爬下来。具体思路:创建driver-----get网页----找到并提取信息-----保存c
- 下面给大家介绍远程连接mysql错误代码1130的解决方法:以上所述是小编给大家介绍的远程连接mysql错误代码1130的解决方法网站的支持
- 本文实例讲述了PHP实现打包下载文件的方法。分享给大家供大家参考,具体如下:/*** 下载文件* @param $img* @return
- 今天遇到了这样一个问题,使用matplotlib绘制热图数组中横纵坐标自然是图片的像素排列顺序,但是这样带来的问题就是画出来的x,y轴中坐标
- (1)、back_log:要求 MySQL 能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程
- 一、邮件发送示例邮件发送示例flask_email及smtplib原生邮件发送示例,适用于基于Flask框架开发,但是内部设置的定时任务发送
- 大数据预测是大数据最核心的应用,是它将传统意义的预测拓展到“现测”。大数据预测的优势体现在,它把一个非常困难的预测问题,转化为一个相对简单的
- ES6 开始,js 新增了剩余参数语法、展开语法等,它们有个共同之处就是都以 ... 这么个符号为前缀,好像很多地方都可以用到,但实际上又不
- 序列概念在分片规则里list、tuple、str(字符串)都可以称为序列,都可以按规则进行切片操作切片操作注意切片的下标0代表顺序的第一个元
- 一、复合查询1.1 多表查询实际开发中往往数据来自不同的表,所以需要多表查询,但是可以将多张表做笛卡尔积后的表当做是一张表,也就是单表查询。
- 一、背景:近期在利用 pycharm 安装第三方库时会提示 pip 不是最新版本, 因此对 pip 进行更新,但是生成最新版本之后, pi