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

 

在這里感謝下很多大神在網站的解答和記錄,對我的學習起了很大的作用。謝謝。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM