zoukankan      html  css  js  c++  java
  • python+tesseract验证码识别的一点小心得

    由于公司需要,最近开始学习验证码的识别

    我选用的是tesseract-ocr进行识别,据说以前是惠普公司开发的排名前三的,现在开源了。到目前为止已经出到3.0.2了

    当然了,前期我们还是需要对验证码进行一些操作,让他对机器更友好,这样才能提高识别率。

    步骤基本上是这样的

    第一步对验证码进行灰度图以及二值化

    需要用到pil库可以pip下载

    代码如下

    def binarization(image):
        #转成灰度图
        imgry = image.convert('L')
        #二值化,阈值可以根据情况修改
        threshold = 128
        table = []
        for i in range(256):
            if i < threshold:
                table.append(0)
            else:
                table.append(1)
        out = imgry.point(table, '1')
        return out

    接着是去噪,因为我研究的验证码基本不需要去噪,所以省略,需要去噪的小伙伴们,请自行谷歌。

    还有倾斜度调整,推荐使用旋转卡壳算法

    原理是对图片进行-30度到30度的旋转,宽度最大的一般就是正的了。(网上这样说的,我试过了,对大部分是可以,小部分如c啥的貌似效果不好)

    归一化

    可以用腐蚀算法对验证码进行细化

    腐蚀算法请自行谷歌。

    第二步对验证码进行切割

    对不同的验证码有不同的算法

    目前我只研究了这几种

    垂直像素直方图

    原理是根据每个x的黑块数量进行切割,黑块数量大于某个值开始切割,小于某个值结束切割。适用于验证码之间有间隔或者间隔较大的,对那种粘连在一起的验证码效果不好。

    平均分割法

    原理是找到黑块开始出现的x,y轴和黑块不出现的x,y轴,切割。然后平均分割成n等分。适用于验证码大小比较固定的,对粘连在一起的验证码效果比上一种方法要好一点。

    波谷分割法

    原理和垂直像素直方图类似,记录每个x的黑块数量,找到局部的极小值,切割。适用于验证码之间有间隔或者间隔较大的,对那种粘连在一起的验证码效果比垂直像素直方图要好。

    滴水算法

    原理是模拟水滴的流动,记录水滴的流动路径,然后进行切割。要注意的是,起始点的确定很重要,对那种粘连在一起的验证码效果很好。

    以上的四种算法以后我会将代码贴在另一个随笔里

    第三步对验证码进行识别

    终于到了重头戏了

    需要导入pytesser,调用image_to_string(image)即可识别。

    不过识别率实在是低的可怜。

    所以需要我们对机器进行训练。

    下面简要介绍下如果对机器进行训练。

    首先下载tesseract-ocr,必须的没有怎么识别对吧。

    找尽量多的验证码,最好是二值化后的或者按照上面的步骤切割下来的。

    下载jTessBoxEditor选择Tools中的merge-tiff,选择要训练的图片,按下shift选择多个,然后保存起来名字如下[lang].[fontname].exp[num].tif 

    生成 .box文件 
    tesseract ec.ufont.exp0.tif ec.ufont.exp0 batch.nochop makebox 

    然后可以通过jTessBoxEditor的Box Editor进行调整可以一张张调整。

    以下摘自http://www.cnblogs.com/wolfray/p/5547267.html

    为了方便 ,将tif命名格式设为[lang].[fontname].exp[num].tif 
    lang是语言 
    fontname是字体 
    比如我们要训练自定义字库 ec 字体名:unfont 
    那么我们把tif文件重命名 ec.ufont.exp0.tif

    生成 .box文件 
    tesseract ec.ufont.exp0.tif ec.ufont.exp0 batch.nochop makebox 
    使用训练过的字库生成.box文件 
    tesseract ec.ufont.exp0.tif ec.ufont.exp0 -l ufont batch.nochop makebox

    然后写一个脚本批量运行以下命令

    脚本内容如下

    num.font.exp0.tif应该改成你自己的文件名字

    rem 执行改批处理前先要目录下创建font_properties文件  
      
    echo Run Tesseract for Training..  
    tesseract.exe num.font.exp0.tif num.font.exp0 nobatch box.train  
      
    echo Compute the Character Set..  
    unicharset_extractor.exe num.font.exp0.box  
    mftraining -F font_properties.txt -U unicharset -O num.unicharset num.font.exp0.tr  
      
    echo Clustering..  
    cntraining.exe num.font.exp0.tr  
      
    echo Rename Files..  
    rename normproto num.normproto  
    rename inttemp num.inttemp  
    rename pffmtable num.pffmtable  
    rename shapetable num.shapetable   
      
    echo Create Tessdata..  
    combine_tessdata.exe num. 

    1. 产生字符特征文件 .tr

    tesseract ec.ufont.exp0.tif ec.ufont.exp0 nobatch box.train 
    这一步将会产生 ec.ufont.exp0.tr文件和一个 ec.ufont.exp0.txt文件,txt文件貌似没什么用,看看而以。

    2.计算字符集(生成unicharset文件) 
    unicharset_extractor ec.ufont.exp0.box

    3.定义字体特征文件 
    —Tesseract-OCR3.01以上的版本在训练之前需要创建一个名称为font_properties.txt的字体特征文件 
    手工建立一个文件font_properties.txt 
    内容如:ufont 0 0 0 0 0 
    注意:这里 必须与训练名中的名称保持一致,填入下面内容 ,这里全取值为0,表示字体不是粗体、斜体等等。

    4.聚集字符特征 
    1) shapeclustering -F font_properties.txt -U unicharset ec.ufont.exp0.tr 
    注意:如果font_properties不加扩展名.txt,可能会报错 
    2) mftraining -F font_properties.txt -U unicharset -O ufont.unicharset ec.ufont.exp0.tr 
    使用上一步产生的字符集文件unicharset,来生成当前新语言的字符集文件ec.unicharset。同时还会产生图形原型文件inttemp和每个字符所对应的字符 
    特征数文件pffmtable。最重要的就是这个inttemp文件了,他包含了所有需要产生的字的图形原型。 
    3)cntraining ec.ufont.exp0.tr 
    这一步产生字符形状正常化特征文件normproto。 
    shapeclustering 操作不是必须的,若没有进行此步,在mftraining的时候 会自动进行。 
    5.改名字 
    把目录下的unicharset、inttemp、pffmtable、shapetable、normproto这五个文件前面都加上ufont.

    6.执行combine_tessdata ufont. 
    然后把ufont.traineddata放到tessdata目录

    7.测试 
    必须确定的是第type 1、3、4、5的数据不是-1,那么一个新的字典就算生成了。 
    tesseract ec.ufont.exp0.tif papapa -l ufont

    tesseract也提出,通过使用多个语言训练库联合使用。如此,新的字体训练库也可以与原有的数据训练库联合使用。如参数 -l 之后 tesseract input.tif output -l eng+newfont。

    cntraining和mftraining只能最多采用32个.tr文件,因此,对于相同的字体,你必须从多种语言中,以字体独立的方式,将所有的文件cat到一起来让32种语言结合在一起。cntraining/mftraining以及unicharset_extractor命令行工具必须各自由给定的.tr和.box文件,以相同的顺序,为不同的字体进行不同的过滤。可以提供一个程序来完成以上的事情,并在字符集表中挑出相同字符集。这样会将事情更简单些。 
    写批处理bat命令的时候,要灵活使用excel里面的填充功能。

    最后记录下训练时遇到的问题

    tesseract.exe eng.font.exp0.tif eng.font.exp0 nobatch box.train

    运行上述命令是可能会遇到could not find a matching blob问题

    请调整你的box大小,或者更换图片

    在此随便解释下box里面的值的含义

    第一个是识别出的值+空格+box起始x坐标+空格+不知道什么鬼的坐标,貌似不是起始y坐标+空格+box终点x坐标即起始x坐标加上宽度+空格+起始y坐标加上高度

    一般来说如果调整了box大小都还报错的话,建议换图

    另一个问题是运行

    mftraining -F font_properties -U unicharset eng.font.exp0.tr

    会报错

    改成运行

    mftraining -F font_properties.txt -U unicharset eng.font.exp0.tr

    就是font_proerties加上.txt

    在这里感谢下很多大神在网站的解答和记录,对我的学习起了很大的作用。谢谢。

  • 相关阅读:
    dp
    数学分析 + 容斥原理
    容斥
    并查集
    矩阵hash + KMP
    扫描线
    位运算
    2015 Multi-University Training Contest 5 1009 MZL's Border
    iOS ZipArchive文件解压缩
    iOS GCD倒计时
  • 原文地址:https://www.cnblogs.com/lgh344902118/p/6672706.html
Copyright © 2011-2022 走看看