python验证码识别的示例代码


Posted in Python onSeptember 21, 2017

写爬虫有一个绕不过去的问题就是验证码,现在验证码分类大概有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的字体路径,也可以在网上下载其他字体使用。生成验证码如下:

python验证码识别的示例代码 

可以看出,验证码有形变。对于这类最简单的验证码,可以直接使用谷歌开源的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')

生成验证码如下:

python验证码识别的示例代码 

识别:

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')

生成验证码如下:

python验证码识别的示例代码 

第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还原,看添加干扰线的情况。

python验证码识别的示例代码 

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

处理后的图片如下:

python验证码识别的示例代码 

可以看出处理后图片锐化了很多,接下来尝试去除干扰线,常见的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

处理后的图片如下:

python验证码识别的示例代码 

好像……根本没卵用啊?!确实是这样的,因为示例中的图片干扰线的宽度和数字是一样的。对于干扰线和数据像素不同的,比如Captcha生成的验证码:

python验证码识别的示例代码 

从左到右依次是原图、二值化、去除干扰线的情况,总体降噪的效果还是比较明显的。另外降噪可以多次执行,比如我对上面的降噪后结果再进行依次降噪,可以得到下面的效果:

python验证码识别的示例代码 

再进行识别得到了结果:

p7 = Image.open('7.png')
tesserocr.image_to_text(p7)
'8069 ,,\n\n'

另外,从图片来看,实际数据颜色明显和噪点干扰线不同,根据这一点可以直接把噪点全部去除,这里就不展开说了。

第一篇文章,先记录如何将图片进行灰度处理、二值化、降噪,并结合tesserocr来识别简单的验证码,剩下的部分在下一篇文章中和大家一起分享。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python多线程学习资料
Dec 19 Python
Python读取环境变量的方法和自定义类分享
Nov 22 Python
Python挑选文件夹里宽大于300图片的方法
Mar 05 Python
Python3.4实现远程控制电脑开关机
Feb 22 Python
python抓取网页内容并进行语音播报的方法
Dec 24 Python
用Python和WordCloud绘制词云的实现方法(内附让字体清晰的秘笈)
Jan 08 Python
Python3+Pycharm+PyQt5环境搭建步骤图文详解
May 29 Python
python 抓包保存为pcap文件并解析的实例
Jul 23 Python
pandas read_excel()和to_excel()函数解析
Sep 19 Python
解决Python数据可视化中文部分显示方块问题
May 16 Python
python 服务器运行代码报错ModuleNotFoundError的解决办法
Sep 16 Python
pycharm激活码免费分享适用最新pycharm2020.2.3永久激活
Nov 25 Python
Python优先队列实现方法示例
Sep 21 #Python
python虚拟环境virtualenv的安装与使用
Sep 21 #Python
基于python socketserver框架全面解析
Sep 21 #Python
基于python select.select模块通信的实例讲解
Sep 21 #Python
Python实现小数转化为百分数的格式化输出方法示例
Sep 20 #Python
Python实现字符串格式化输出的方法详解
Sep 20 #Python
Python+Selenium+PIL+Tesseract自动识别验证码进行一键登录
Sep 20 #Python
You might like
DC漫画《蝙蝠侠和猫女》图透 猫女怀孕老爷当爹
2020/04/09 欧美动漫
使用 MySQL 开始 PHP 会话
2006/12/21 PHP
swfupload 多文件上传实现代码
2008/08/27 PHP
php UBB 解析实现代码
2011/11/27 PHP
在windows服务器开启php的gd库phpinfo中未发现
2013/01/13 PHP
PHP中imagick函数的中文解释
2015/01/21 PHP
php实现无限级分类查询(递归、非递归)
2016/03/10 PHP
Yii2实现ajax上传图片插件用法
2016/04/28 PHP
php+mysql+ajax 局部刷新点赞/取消点赞功能(每个账号只点赞一次)
2020/07/24 PHP
use jscript with List Proxy Server Information
2007/06/11 Javascript
js与css实现弹出层覆盖整个页面的方法
2014/12/13 Javascript
JavaScript DOM事件(笔记)
2015/04/08 Javascript
继续学习javascript闭包
2015/12/03 Javascript
Node.js+Express配置入门教程
2016/05/19 Javascript
AngularJS ng-change 指令的详解及简单实例
2016/07/30 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
原生javascript上传图片带进度条【实例分享】
2017/04/06 Javascript
JavaScript选取(picking)和反选(rejecting)对象的属性方法
2017/08/16 Javascript
详解在express站点中使用ejs模板引擎
2017/09/21 Javascript
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
python自然语言编码转换模块codecs介绍
2015/04/08 Python
python使用socket进行简单网络连接的方法
2015/04/29 Python
Python assert关键字原理及实例解析
2019/12/13 Python
Python3运算符常见用法分析
2020/02/14 Python
关于python 跨域处理方式详解
2020/03/28 Python
Python pathlib模块使用方法及实例解析
2020/10/05 Python
德国团购网站:Groupon德国
2018/03/13 全球购物
澳大利亚领先的折扣药房:Chemist Direct(有中文站)
2018/11/24 全球购物
Converse匡威法国官网:美国著名帆布鞋品牌
2018/12/05 全球购物
公司培训心得体会
2014/01/03 职场文书
机关会计岗位职责
2014/04/08 职场文书
《火烧云》教学反思
2014/04/12 职场文书
代办委托书怎么写
2014/08/01 职场文书
小学运动会演讲稿
2014/08/25 职场文书
2015年女生节活动总结
2015/02/27 职场文书