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实现Linux下守护进程的编写方法
Aug 22 Python
在Python中使用__slots__方法的详细教程
Apr 28 Python
梯度下降法介绍及利用Python实现的方法示例
Jul 12 Python
Python实现的KMeans聚类算法实例分析
Dec 29 Python
python 对多个csv文件分别进行处理的方法
Jan 07 Python
Python实例方法、类方法、静态方法的区别与作用详解
Mar 25 Python
浅谈Python小波分析库Pywavelets的一点使用心得
Jul 09 Python
Python for循环与getitem的关系详解
Jan 02 Python
基于Python fminunc 的替代方法
Feb 29 Python
VS2019+python3.7+opencv4.1+tensorflow1.13配置详解
Apr 16 Python
Python logging日志模块 配置文件方式
Jul 12 Python
Python同时处理多个异常的方法
Jul 28 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
php中文本操作的类
2007/03/17 PHP
判断是否为指定长度内字符串的php函数
2010/02/16 PHP
优化php效率,提高php性能的一些方法
2011/03/24 PHP
PHP变量的定义、可变变量、变量引用、销毁方法
2013/12/20 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
PHP页面间传递值和保持值的方法
2016/08/24 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
使用PHP访问RabbitMQ消息队列的方法示例
2018/06/06 PHP
php数值计算num类简单操作示例
2020/05/15 PHP
读jQuery之十三 添加事件和删除事件的核心方法
2011/08/23 Javascript
jquery动画3.创建一个带遮罩效果的图片走廊
2012/08/24 Javascript
JS跨域总结
2012/08/30 Javascript
JavaScript mapreduce工作原理简析
2012/11/25 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
2015/03/02 Javascript
jquery实现弹出层登录和全屏层注册特效
2015/08/28 Javascript
Node.js Sequelize如何实现数据库的读写分离
2016/10/23 Javascript
VUE axios发送跨域请求需要注意的问题
2017/07/06 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
微信小程序登录数据解密及状态维持实例详解
2019/05/06 Javascript
vue 获取及修改store.js里的公共变量实例
2019/11/06 Javascript
通过高德地图API获得某条道路上的所有坐标用于描绘道路的方法
2020/08/24 Javascript
python安装numpy&amp;安装matplotlib&amp; scipy的教程
2017/11/02 Python
Python使用itertools模块实现排列组合功能示例
2018/07/02 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
Python基于pandas爬取网页表格数据
2020/05/11 Python
如何实现一个自定义类的序列化
2012/05/22 面试题
AJAX的优缺点都有什么
2015/08/18 面试题
优秀的计算机专业求职信范文
2013/12/27 职场文书
《冬阳童年骆驼队》教学反思
2014/04/15 职场文书
诚实守信演讲稿
2014/09/01 职场文书
优秀教师事迹材料
2014/12/15 职场文书
土地租赁协议书
2015/01/29 职场文书
幼儿园大班个人总结
2015/02/28 职场文书
千与千寻观后感
2015/06/04 职场文书
导游词之京东大峡谷旅游区
2019/10/29 职场文书
CocosCreator入门教程之网络通信
2021/04/16 Javascript