简单识别

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库中运入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识别图形验证码的更多相关文章

  1. mac使用python识别图形验证码

    前言 最近在研究验证码相关的操作,所以准备记录下安装以及使用的过程.虽然之前对验证码的破解有所了解的,但是之前都是简单使用之后就不用了,没有记录一个详细的过程,所以后面再用起来也要重新从网上查找资料比 ...

  2. 利用python生成图形验证码

    validCode.py import random from io import BytesIO from PIL import Image, ImageDraw, ImageFont def ge ...

  3. WEB安全新玩法 [6] 防范图形验证码重复使用

    在完成关键业务操作时,要求用户输入图形验证码是防范自动化攻击的一种措施.为安全起见,即使针对同一用户,在重新输入信息时也应该更新图形验证码.iFlow 业务安全加固平台可以加强这方面的处理. 某网站系 ...

  4. Python Selenium、PIL、pytesser 识别验证码

    思路: 使用Selenium库把带有验证码的页面截取下来 利用验证码的xpath截取该页面的验证码 对验证码图片进行降噪.二值化.灰度化处理后再使用pytesser识别 使用固定的账户密码对比验证码正 ...

  5. 爬虫(十二):图形验证码的识别、滑动验证码的识别(B站滑动验证码)

    1. 验证码识别 随着爬虫的发展,越来越多的网站开始采用各种各样的措施来反爬虫,其中一个措施便是使用验证码.随着技术的发展,验证码也越来越花里胡哨的了.最开始就是几个数字随机组成的图像验证码,后来加入 ...

  6. Tornado框架实现图形验证码功能

    图形验证码是项目开发过程中经常遇到的一个功能,在很多语言中都有对应的不同形式的图形验证码功能的封装,python 中同样也有类似的封装操作,通过绘制生成一个指定的图形数据,让前端HTML页面通过链接获 ...

  7. 图形验证码 tesserocr pillow

    利用tesserocr和pil生成图形验证码 import tesserocr from PIL import Image image = Image.open('222.jpg') image = ...

  8. selenium基础-图形验证码

    selenium基础-图形验证码 一.图形验证码作用 设计的初衷其实就是为了防自动化,防止一些人利用自动工具恶意攻击网站 二.图形验证码是由客户端生成还是由服务器端生成的? 图形验证码是由服务器端生成 ...

  9. Python脚本破解图形验证码(tesserocr和pytesseract)

    在学习之前,我们先了解OCR.tesseract.tesserocr.pytesseract和opencv这几个跟图片处理有关的库. OCR(Optical Character Recognition ...

随机推荐

  1. hadoop分布式安装部署详细视频教程(网盘附配好环境的CentOS虚拟机文件/hadoop配置文件)

    参考资源下载:http://pan.baidu.com/s/1ntwUij3视频安装教程:hadoop安装.flvVirtualBox虚拟机:hadoop.part1-part5.rarhadoop文 ...

  2. 初探linux子系统集之led子系统(二)

    巴西世界杯,德国7比1东道主,那个惨不忍睹啊,早上起来看新闻,第一眼看到7:1还以为点球也能踢成这样,后来想想,点球对多嘛6比1啊,接着就是各种新闻铺天盖地的来了.其实失败并没有什么,人生若是能够成功 ...

  3. javascript语言扩展:可迭代对象(4)

    js 1.7中还包含一个数组推导(array comprehension)的特性,如果不在最后介绍它好像显得不怎么完整. 数组推导其实很简单: let a = [x*x for(x in range( ...

  4. rubygem若干常用选项参数

    可以用gem help commands看所有支持的参数,这个比gem -h显示的全: wisy@wisy-ThinkPad-X61:~/src/ruby_src$ gem help commands ...

  5. Mac环境svn的使用

    在Windows环境中,我们一般使用TortoiseSVN来搭建svn环境.在Mac环境下,由于Mac自带了svn的服务器端和客户端功能,所以我们可以在不装任何第三方软件的前提下使用svn功能,不过还 ...

  6. Jhipster 学习(一)jhipster构建项目

    如何安装jhipster 第一步:下载jdk  自己安装的1.8版本  (安装.环境变量配置略) 第二步:1.下载Eclipse (luna版 eclipse-4.4.1) 第三步:下载maven ( ...

  7. HP-Socket快速入门:分包、粘包解析

    环境配置 vs2015 windows7 64位 hp-socket 5.0 安装hp-socket 新建控制台项目TelnetServer,打开Nuget管理工具,搜索hp-socket: 安装成功 ...

  8. valid sudoku(数独)

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

  9. webservice入门简介

    为了梦想,努力奋斗! 追求卓越,成功就会在不经意间追上你 webservice入门简介 1.什么是webservice? webservice是一种跨编程语言和跨操作系统平台的远程调用技术. 所谓的远 ...

  10. 解决记录:win10 无法安装VS2017,visual studio installer下载进度始终为0

    问题描述:win10 下无法安装VS2017,visual studio installer下载进度始终为0,点击取消按钮后,也没有反应,visual studio installer也关闭不掉: 具 ...