利用pytesser识别图形验证码
简单识别
1.一般思路
验证码识别的一般思路为:
- 图片降噪
- 图片切割
- 图像文本输出
1.1 图片降噪
所谓降噪就是把不需要的信息通通去除,比如背景,干扰线,干扰像素等等,只剩下需要识别的文字,让图片变成2进制点阵最好。
对于彩色背景的验证码:每个像素都可以放在一个5维的空间里,这5个维度分别是,X,Y,R,G,B,也就是像素的坐标和颜色,在计算机图形学中,有很多种色彩空间,最常用的比如RGB,印刷用的CYMK,还有比较少见的HSL或者HSV,每种色彩空间的维度都不一样,但是可以通过公式互相转换。在RGB空间中不好区分颜色,可以把色彩空间转换为HSV或HSL。色彩空间参见 http://baike.baidu.com/view/3427413.htm
验证码图片7039.jpg
:

1、导入Image包,打开图片:
from PIL import Image im = Image.open('7039.jpg')
2、把彩色图像转化为灰度图像。RBG转化到HSI彩色空间,采用I分量:
imgry = im.convert('L') imgry.show()
灰度看起来是这样的:

3、二值化处理
二值化是图像分割的一种常用方法。在二值化图象的时候把大于某个临界灰度值的像素灰度设为灰度极大值,把小于这个值的像素灰度设为灰度极小值,从而实现二值化(一般设置为0-1)。根据阈值选取的不同,二值化的算法分为固定阈值和自适应阈值,这里选用比较简单的固定阈值。
把像素点大于阈值的设置,1,小于阈值的设置为0。生成一张查找表,再调用point()进行映射。
threshold = 140 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) out = imgry.point(table, ') out.show()
或者用匿名函数
from PIL import Image im = Image.open("7364.jpg") im_gary = im.point(lambda x: 0 if x<143 else 255) #二值化处理 im_gary.show()
处理结果看起来是这样的:

2. 图片切割
识别验证码的重点和难点就在于能否成功分割字符,对于颜色相同又完全粘连的字符,比如google的验证码,目前是没法做到5%以上的识别率的。不过google的验证码基本上人类也只有30%的识别率。本文使用的验证码例子比较容易识别。可以不用切割,有关图片切割的方法参见这篇博客:http://www.cnblogs.com/apexchu/p/4231041.html
3.利用pytesser模块实现识别
pytesser是谷歌OCR开源项目的一个模块,在python中导入这个模块即可将图片中的文字转换成文本。
链接:https://code.google.com/p/pytesser/
pytesser 调用了 tesseract。在python中调用pytesser模块,pytesser又用tesseract识别图片中的文字。
3.1 pytesser安装
简单识别安装
- 把下载下来的
pytesser
包解压到python目录的Lib/site_packages
里面,名字取为pytesser
, - 然后再在这个目录下面新建一个
pytesser.pth
文件,内容为pytesser
或者新建一个__init__.py
空白文件, - 然后修改
pytesser.py
,把第一句的import Image
修改为from PIL import Image
,这一步的原因是这里我们用的是pillow而不是用的原生PIL。 - pytesser里包含了
tesseract.exe
和英语的数据包(默认只识别英文),还有一些示例图片,所以解压缩后即可使用。
这样做好以后记得把pytesser
这个目录放入到系统环境变量,因为程序会调用这个目录里面的tesseract.exe
,如果不放到环境变量会因为找不到这个文件而抛出异常。
简单识别代码
# -*- coding:utf-8 -*- from PIL import Image from pytesser import pytesser im = Image.open(r'C:\Users\Administrator\Desktop\1.png') imgry = im.convert('L') # imgry.show() threshold = 140 table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) out = imgry.point(table, ') out.show() text = pytesser.image_to_string(out) # 将图片转成字符串 print text.replace(' ', '').replace('\n', '') #这里因为识别出来的文字可能会有空格和回车
复杂识别安装
- 如果没有安装PIL,请到这里下载安装:http://www.pythonware.com/products/pil/
- 安装pytesser,下载地址:http://code.google.com/p/pytesser/ ,下载后直接将其解压到项目代码下,或者解压到python安装目录的
Libsite-packages
下,并将其添加到path
环境变量中,不然在导入模块时会出错。 - 下载Tesseract OCR engine:http://code.google.com/p/tesseract-ocr/ ,下载后解压,找到tessdata文件夹,用其替换掉pytesser解压后的tessdata文件夹即可。
另外如果现在都是从PIL库中运入Image,没有使用Image模块,所以需要把pytesser.py
中的import Image
改为from PIL import Image
, 其次还需要在pytesser
文件夹中新建一个__init__.py
的空文件。
3.2 调用pytesser识别
pytesser提供了两种识别图片方法,通过image对象和图片地址,代码判断如下:
from PIL import Image from pytesser import pytesser image = Image.open('7039.jpg') #通过打开的文件识别 print pytesser.image_to_string(image) #通过文件路径直接识别 print pytesser.image_file_to_string('7039.jpg')
同时pytesser还支持其他语言的识别,比如中文。具体参见:http://www.tuicool.com/articles/amQJR3
3.3解决识别率低的问题
可以增强图片的显示效果,或者将其转换为黑白的,这样可以使其识别率提升不少:
from PIL import ImageEnhance image = Image.open(r'C:\Users\Administrator\Desktop\1.png') enhancer = ImageEnhance.Contrast(image) image2 = enhancer.enhance(4)
可以再对image2调用image_to_string
识别
3.4识别其他语言
tesseract
是一个命令行下运行的程序,参数如下:
tesseract imagename outbase [-l lang] [-psm N] [configfile...]
imagename
是输入的image
的名字
outbase
是输出的文本的名字,默认为outbase.txt
-l lang
是定义要识别的的语言,默认为英文
- 通过以下步骤可以识别其他语言:
(1)、下载其他语言数据包:
https://code.google.com/p/tesseract-ocr/downloads/list
将语言包放入pytesser的tessdata文件夹下
要识别其他语言只要添加一个language
参数就行了,下面是我的例子:
"""OCR in Python using the Tesseract engine from Google http://code.google.com/p/pytesser/ by Michael J.T. O'Kelly V 0.0.1, 3/10/07""" from PIL import Image import subprocess import util import errors tesseract_exe_name = 'D:\\Python2.7\\Lib\\site-packges\\pytesser\\tesseract' # Name of executable to be called at command line scratch_image_name = "temp.bmp" # This file must be .bmp or other Tesseract-compatible format scratch_text_name_root = "temp" # Leave out the .txt extension cleanup_scratch_flag = True # Temporary files cleaned up after OCR operation def call_tesseract(input_filename, output_filename, language): """Calls external tesseract.exe on input file (restrictions on types), outputting output_filename+'txt'""" args = [tesseract_exe_name, input_filename, output_filename, "-l", language] proc = subprocess.Popen(args) retcode = proc.wait() if retcode!=0: errors.check_for_errors() def image_to_string(im, cleanup = cleanup_scratch_flag, language = "eng"): """Converts im to file, applies tesseract, and fetches resulting text. If cleanup=True, delete scratch files after operation.""" try: util.image_to_scratch(im, scratch_image_name) call_tesseract(scratch_image_name, scratch_text_name_root,language) text = util.retrieve_text(scratch_text_name_root) finally: if cleanup: util.perform_cleanup(scratch_image_name, scratch_text_name_root) return text def image_file_to_string(filename, cleanup = cleanup_scratch_flag, graceful_errors=True, language = "eng"): """Applies tesseract to filename; or, if image is incompatible and graceful_errors=True, converts to compatible format and then applies tesseract. Fetches resulting text. If cleanup=True, delete scratch files after operation.""" try: try: call_tesseract(filename, scratch_text_name_root, language) text = util.retrieve_text(scratch_text_name_root) except errors.Tesser_General_Exception: if graceful_errors: im = Image.open(filename) text = image_to_string(im, cleanup) else: raise finally: if cleanup: util.perform_cleanup(scratch_image_name, scratch_text_name_root) return text if __name__=='__main__': im = Image.open('phototest.tif') text = image_to_string(im) print text try: text = image_file_to_string('fnord.tif', graceful_errors=False) except errors.Tesser_General_Exception, value: print "fnord.tif is incompatible filetype. Try graceful_errors=True" print value text = image_file_to_string('fnord.tif', graceful_errors=True) print "fnord.tif contents:", text text = image_file_to_string('fonts_test.png', graceful_errors=True) print text
在调用image_to_string
函数时,只要加上相应的language
参数就可以了,如简体中文最后一个参数即为 chi_sim
, 繁体中文chi_tra
,
也就是下载的语言包的XXX.traineddata
文件的名字XXX
,如下载的中文包是chi_sim.traineddata
, 参数就是chi_sim
:
text = image_to_string(self.im, language = 'chi_sim')
至此,图片识别就完成了。
额外附加一句:有可能中文识别出来了,但是乱码,需要相应地将text转换为你所用的中文编码方式,如:
text.decode("utf8")
就可以了
利用pytesser识别图形验证码的更多相关文章
- mac使用python识别图形验证码
前言 最近在研究验证码相关的操作,所以准备记录下安装以及使用的过程.虽然之前对验证码的破解有所了解的,但是之前都是简单使用之后就不用了,没有记录一个详细的过程,所以后面再用起来也要重新从网上查找资料比 ...
- 利用python生成图形验证码
validCode.py import random from io import BytesIO from PIL import Image, ImageDraw, ImageFont def ge ...
- WEB安全新玩法 [6] 防范图形验证码重复使用
在完成关键业务操作时,要求用户输入图形验证码是防范自动化攻击的一种措施.为安全起见,即使针对同一用户,在重新输入信息时也应该更新图形验证码.iFlow 业务安全加固平台可以加强这方面的处理. 某网站系 ...
- Python Selenium、PIL、pytesser 识别验证码
思路: 使用Selenium库把带有验证码的页面截取下来 利用验证码的xpath截取该页面的验证码 对验证码图片进行降噪.二值化.灰度化处理后再使用pytesser识别 使用固定的账户密码对比验证码正 ...
- 爬虫(十二):图形验证码的识别、滑动验证码的识别(B站滑动验证码)
1. 验证码识别 随着爬虫的发展,越来越多的网站开始采用各种各样的措施来反爬虫,其中一个措施便是使用验证码.随着技术的发展,验证码也越来越花里胡哨的了.最开始就是几个数字随机组成的图像验证码,后来加入 ...
- Tornado框架实现图形验证码功能
图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...
- 图形验证码 tesserocr pillow
利用tesserocr和pil生成图形验证码 import tesserocr from PIL import Image image = Image.open('222.jpg') image = ...
- selenium基础-图形验证码
selenium基础-图形验证码 一.图形验证码作用 设计的初衷其实就是为了防自动化,防止一些人利用自动工具恶意攻击网站 二.图形验证码是由客户端生成还是由服务器端生成的? 图形验证码是由服务器端生成 ...
- Python脚本破解图形验证码(tesserocr和pytesseract)
在学习之前,我们先了解OCR.tesseract.tesserocr.pytesseract和opencv这几个跟图片处理有关的库. OCR(Optical Character Recognition ...
随机推荐
- Universal-Image-Loader源码分析,及常用的缓存策略
讲到图片请求,主要涉及到网络请求,内存缓存,硬盘缓存等原理和4大引用的问题,概括起来主要有以下几个内容: 原理示意图 主体有三个,分别是UI,缓存模块和数据源(网络).它们之间的关系如下: ① UI: ...
- objective-c中的method swizz实现"猴打补丁"
ruby中的猴打补丁很好实现,下面给出例子: class String alias :org_upcase :upcase def upcase puts("trace me if you ...
- Oracle 中Return 和exit的区别
在Oracle存储过程中,使用Return 时,如果执行到Return语句,会跳出整个语句(如果是循环,会跳出整个循环),将不再执行,也就是结束了整个存储过程. 下面就用一个例子来说明一下 ,这个存储 ...
- C# / VB.NET合并PDF指定页
在前面的文章中,我们已经知道如何合并.拆分多个PDF文件,在这篇文章中的合并.拆分PDF文档主要是以方便文档管理的目的来操作文档,在文档查阅.管理及存储上很方便实用.但是我们如果想要合并多个文档中的部 ...
- Mac 下安装安卓 apk 文件
Mac 下安装安卓 apk 文件 在windows上有比较多的第三方软件可以使用,双击就可以将apk文件安装到手机上. 在Mac 上要实现这样还是挺难得,目前还没有像Windows那样的第三方软件可以 ...
- ionic1 下拉刷新 上拉加载 功能
html页面如下 <ion-content> <ion-refresher pulling-text="刷新" on-refresh="search() ...
- 小议 HashMap
大家都知道,在Java里对对象的操作是基于引用的.而当我们需要对一组对象操作的时候,就需要有接收这一组引用的容器.平时我们最常用的就是数组.在Java里可以定义一个对象数组来完成许多操作.可是,数组长 ...
- FFPLAY的原理(七)
同步音频 现在我们已经有了一个比较像样的播放器.所以让我们看一下还有哪些零碎的东西没处理.上次,我们掩饰了一点同步问题,也就是同步音频到视频而不是其它的同 步方式.我们将采用和视频一样的方式:做一个内 ...
- How Microservices are Transforming Python Development
https://blog.appdynamics.com/engineering/how-microservices-are-transforming-python-development/ Summ ...
- A million requests per second with Python
https://medium.freecodecamp.com/million-requests-per-second-with-Python-95c137af319 Is it possible t ...