关于利用python进行验证码识别的一些想法

 


        用python加“验证码”为关键词在baidu里搜一下,能够找到不少关于验证码识别的文章。我大致看了一下,主要方法有几类:一类是经过对图片进行处理,而后利用字库特征匹配的方法,一类是图片处理后创建字符对应字典,还有一类是直接利用ocr模块进行识别。无论是用什么方法,都须要首先对图片进行处理,因而试着对下面的验证码进行分析。
        1、图片处理python

 


        这个验证码中主要的影响因素是中间的曲线,首先考虑去掉图片中的曲线。考虑了两种算法:
        第一种是首先取到曲线头的位置,即x=0时,黑点的位置。而后向后移动x的取值,观察每一个x下黑点的位置,判断先后两个相邻黑点之间的距离,若是距离在必定范围内,能够基本判断该点是曲线上的点,最后将曲线上的点所有绘成白色。试了一下这种方法,结果获得的图片效果很通常,曲线不能彻底去除,并且容量将字符的线条去除。
        第二种考虑用单位面积内点的密度来进行计算。因而首先计算单位面积内点的个数,将单位面积内点个数少于某一指定数的面积去除,剩余的部分基本上就是验证码字符的部分。本例中,为了便于操做,取了5*5作为单位范围,并调整单位面积内点的标准密度为11。处理后的效果:算法



        2、字符验证
        这里我使用的方法是利用pytesser进行ocr识别,但因为这类验证码字符的不规则性,使得验证结果的准确性并非很高。具体哪位大牛,有什么好的办法,但愿能给指点一下。
        3、准备工做与代码实例
        一、PIL、pytesser、tesseract
        (1)安装PIL:下载地址:http://www.pythonware.com/products/pil/
        (2)pytesser:下载地址:http://code.google.com/p/pytesser/,下载解压后直接放在代码相同的文件夹下,便可使用。
        (3)Tesseract OCR engine下载:http://code.google.com/p/tesseract-ocr/,下载后解压,找到tessdata文件夹,用其替换掉pytesser解压后的tessdata文件夹便可。
        二、具体代码ide

复制代码
#encoding=utf-8
###利用点的密度计算
import Image,ImageEnhance,ImageFilter,ImageDraw
import sys
from pytesser import *
#计算范围内点的个数
def numpoint(im):
    w,h = im.size
    data = list( im.getdata() )
    mumpoint=0
    for x in range(w):
        for y in range(h):
            if data[ y*w + x ] !=255:#255是白色
                mumpoint+=1
    return mumpoint
                
#计算5*5范围内点的密度
def pointmidu(im):
    w,h = im.size
    p=[]
    for y in range(0,h,5):
        for x in range(0,w,5):
            box = (x,y, x+5,y+5)
            im1=im.crop(box)
            a=numpoint(im1)
            if a<11:##若是5*5范围内小于11个点,那么将该部分所有换为白色。
                for i in range(x,x+5):
                    for j in range(y,y+5):
                        im.putpixel((i,j), 255)
    im.save(r'img.jpg')
        
def ocrend():##识别
    image_name = "img.jpg"
    im = Image.open(image_name)
    im = im.filter(ImageFilter.MedianFilter())
    enhancer = ImageEnhance.Contrast(im)
    im = enhancer.enhance(2)
    im = im.convert('1')
    im.save("1.tif")
    print image_file_to_string('1.tif')    
    
if __name__=='__main__':
    image_name = "1.png"
    im = Image.open(image_name)
    im = im.filter(ImageFilter.DETAIL)
    im = im.filter(ImageFilter.MedianFilter())
    
    enhancer = ImageEnhance.Contrast(im)
    im = enhancer.enhance(2)
    im = im.convert('1')
    ##a=remove_point(im)
    pointmidu(im)
    ocrend()
复制代码

本人的这个方法,最终识别率确实不高,写出来,哪位高手有好的思路或者作法,望不惜赐教!google

相关文章
相关标签/搜索