2012年8月3日 星期五

Training Tesseract OCR 3.0.1

20111106049.jpg
最近在研究車牌辨識

找上了歷史相當久遠的Tesseract

Tesseract屬於開放原始碼,並在Google code中維護

Tesseract的討論相當多,但是對於訓練(traning)的著墨是少之又少

幾乎千篇一律是Tesseract 2.0的翻譯文(直接從官網翻譯出來的文章)

這次整理把之前的介紹版本做一些修正和補充


詳細內容還是得參考官方網站:Traning Tesseract 3.0

以下是我整理的訓練步驟:



一. 先到Tesseract下載頁面下載這個檔案:

tesseract-ocr-setup-3.01-1.exe



二. 下載完後直接安裝 tesseract-ocr-setup-3.01-1.exe



三. 將所收集到的某字體的字母二值化後做成一張 .tif 的圖檔。
(小畫家即可製作)

如下圖所示:


eng.segoe.exp1.tif

將此圖檔(eng.segoe.exp1.tif)放在安裝目錄(Tesseract-OCR)下

這裡檔名代表的意思就是:語言.字形.範本.tif

此範例的意思就是:語言:英文,字形:segoe,範例:exp1



四. 系統管理員身分執行命令提示字元

到剛剛的安裝目錄底下(C:\Program Files (x86)\Tesseract-OCR),

執行下面的command line:
tesseract eng.timesitalic.exp0.tif eng.timesitalic.exp0 batch.nochop makebox

紅色部分是需要替換的文字,例子如下:
tesseract eng.segoe.exp1.tif eng.segoe.exp1 batch.nochop makebox

此時會產生一個.box的檔案(eng.segoe.exp1.box)

這是tesseract初步辨識出來的結果

包含每個字元的上下左右邊界,和辨識出來的結果

如果不用軟體去解析看起來會很雜亂,如下:

A 5 391 24 413 0 B 35 391 48 413 0 C 59 391 76 413 0 D 88 391 106 413 0 E 118 391 130 413 0 F 142 391 153 413 0 ...

但他應該是要這樣看的:

A 5 391 24 413 0
B 35 391 48 413 0
C 59 391 76 413 0
D 88 391 106 413 0
E 118 391 130 413 0
F 142 391 153 413 0
...

最左邊的是符號,也就是初步辨識出來的結果
(如果相對應有錯~就要在此修正)

第二位的數字代表的意思是:此字元的左邊界與影像的左邊界的距離
第二位數字是:此字元的下邊界與影像的下邊界的距離
第三位數字是:此字元的右邊界與影像的左邊界的距離
第四位數字是:此字元的上邊界與影像的下邊界的距離

這不是繞口令,直接看圖解比較清楚:


這是將原圖放大來看

第一位的數字代表的就是L1的長度(pixels):5

第二位的數字代表的就是L4的長度(pixels):391

第三位的數字代表的就是L2的長度(pixels):24

第四位的數字代表的就是L3的長度(pixels):413

有時候,甚至連這些長度都要做修正!!



五.利用記事本打開.box檔(eng.segoe.exp1.box)

去修正裡面有錯的部分,也可利用一些軟體來修正。(詳情請參考Traning Tesseract 3.0)



六. 接著執行:
tesseract lang.timesitalic.exp0.tif lang.timesitalic.exp0 nobatch box.train

紅色一樣是需要替換的部分,例子如下:
tesseract eng.segoe.exp1.tif eng.segoe.exp1 nobatch box.train

此時會產生兩個檔案:

.tr檔(eng.segoe.exp1.tr) .txt檔(eng.segoe.exp1.txt)

(原本tesseract-ocr-setup-3.00.exe會在此步驟產生log檔方便查看是否有錯誤發生。)




七. 接著執行:
unicharset_extractor lang.timesitalic.exp0.box

紅色一樣是需要替換的部分,例子如下:
unicharset_extractor eng.segoe.exp1.box

此時會跑出一個檔案:unicharset



八. 接著在安裝目錄(Tesseract-OCR)下新增一個純文字檔

內容打上:<fontname> <italic> <bold> <fixed> <serif> <fraktur>

本篇的例子如下:segoe 0 0 0 0 0

(這裡的字形名稱一定要跟你一開始設定的字形名稱相符合!!)

並另存新檔,存檔類型改成所有檔案,檔案名稱為:font_properties

這是用來做此字型的訓練內容(也就是.tif圖檔)的屬性設定

意思就是:某字體 是否斜體 是否粗體 是否固定 是否是櫬線字體 是否是fraktur字體
(屬性就是用0和1去控制。)



九. 接著執行:
mftraining -F font_properties -U unicharset lang.timesitalic.exp0.tr
(font_properties就是剛剛新增出來的純文字)

紅色一樣是需要替換的部分,例子如下:
mftraining -F font_properties -U unicharset eng.segoe.exp1.tr

此時會跑出四個檔案:inttemp, mfunicharset, Microfeat, pffmtable



十一. 接著執行:
cntraining lang.timesitalic.exp0.tr

紅色一樣是需要替換的部分,例子如下:
cntraining eng.segoe.exp1.tr

此時會多出一個檔案:normproto



十二. (最容易忽略的步驟)

接著把剛剛產生的六個檔案:
unicharset, Microfeat, normproto, pffmtable, mfunicharset, inttemp

重新命名,在前面加上:lang. ,替換例子如下:
eng.unicharset, eng.Microfeat, eng.normproto, eng.pffmtable, eng.mfunicharset, eng.inttemp



十三. 接著執行:
combine_tessdata lang.

紅色一樣是需要替換的部分,例子如下:
combine_tessdata eng.

畫面會出現類似的文字:

Combining tessdata files
TessdataManager combined tesseract data files.
Offset for type 0 is -1
Offset for type 1 is 108
Offset for type 2 is -1
Offset for type 3 is 1385
Offset for type 4 is 308254
Offset for type 5 is 308442

Offset for type 6 is -1
Offset for type 7 is -1
Offset for type 8 is -1
Offset for type 9 is -1
Offset for type 10 is -1
Offset for type 11 is -1
Offset for type 12 is -1


依照上述的步驟執行的話,至少這四行紅色部分不能為-1,否則就是失敗!

此時會跑出最後一個檔案:.traineddata(eng.traineddata)

也就是最後的訓練文檔



十四. 最後進行測試前

需要先把產生出來的.traineddata(eng.traineddata)檔

複製到安裝目錄(
Tesseract-OCR)下的tessdata資料夾

(記得先備份原本在裡面的eng.traineddata)

然後執行:
tesseract image.tif output -l lang

紅色一樣是需要替換的部分,我們拿之前的訓練圖檔來測試,例子如下:
tesseract eng.segoe.exp1.tif output -l eng

會產生一個output.txt

裡面就是Tesseract OCR 3.0透過你的訓練文檔來辨識出來的結果!!

11 則留言:

  1. 你好
    我怎麼知道我要辨識的圖文是什麼字形的呢???

    我如果沒有設定字形去跑上面的流程...
    在第八步

    八. 接著在安裝目錄(Tesseract-OCR)下新增一個純文字檔

    內容打上:

    就出現錯誤了

    Warning: No shape table file present: shapetable
    Reading aaa.tr ...
    Font id = -1/0, class id = 1/5 on sample 0
    font_id >= 0 && font_id < font_id_map_.SparseSize():Error:Assert failed:in file
    ..\..\classify\trainingsampleset.cpp, line 622

    回覆刪除
  2. 你好~由於Tesseract OCR是可以訓練多個字形的,所以必須在訓練的時候給定訓練資料的字形,字形的名稱你可以自行給定(可以隨便亂取個名稱!),所以第八步驟你的純文字檔內容可以是:MyFont 0 0 0 0 0、GoodFont 0 0 0 0 0、TrainingFont 0 0 0 0 0...前面那個XXXFont你可以隨意更換。 強烈建議在一開始的訓練中就把檔名設定清楚,如第三步驟的圖檔檔名:eng.segoe.exp1.tif(此範例的意思就是:語言:英文,字形:segoe),不然會很容易混淆!

    回覆刪除
  3. 你好,
    我想問這訓練有甚麼用?
    是否做了某字型的訓練會對該字型更快更準?
    另外我想問你一個問題在 http://code.google.com/p/tesseract-ocr/wiki/FAQ
    我想OCR 數字 要連這句,tesseract image.tif outputbase nobatch digits ; image.tif哪裡來的.
    Thank you.

    回覆刪除
  4. 你好,在Tesseract OCR官方所訓練出來的資料其實已經相當完整,可以先利用官方的訓練資料來做辨識,若是效果很好就可以不必再做訓練。但若是效果不佳,表示你所要辨識的字體和字型對於原本的訓練資料來說是不足的,此時就必須加入自己的訓練資料,才能夠提升辨識的準確率。
    而第二個問題, image.tif就是你要辨識的數字影像(影像格式是tif檔),丟入你要辨識的影像,tesseract才有辦法告訴你結果。

    回覆刪除
  5. 張維庭.
    感謝你這篇文章, 我從新做了訓練, 結果對OCR效果好很多.

    回覆刪除
    回覆
    1. 感謝你的觀看,希望這篇文章能夠幫助到有需要的人。

      刪除
  6. 作者已經移除這則留言。

    回覆刪除
  7. 您好,感謝您的文章 幫助很大
    我碰到一個問題
    我參考Emgu中的範例(LicensePlateRecognition)
    在VS 2010 C#專案中撰寫的一段程式碼
    -------------------------------------------------------------------------------------------------------------
    Tesseract _ocr;
    _ocr=new Tesseract(@"D:\emgucv2_3\bin\tessdata",
    "eng", Tesseract.OcrEngineMode.OEM_TESSERACT_CUBE_COMBINED);
    -------------------------------------------------------------------------------------------------------------
    使用本來的eng.traineddata就沒問題
    但一旦將自己訓練好的eng.trainedata(已經試過在commandline底下可以運作)覆蓋過去後
    在new那行會產生AccessViolationException
    想請問您有沒有遇到這個問題 有解決的辦法嗎

    回覆刪除
  8. 你好,不知道你是否有發現EmguCV提供的tessdata裡面包含的檔案項目,
    其實不單單只有Tesseract的訓練檔(eng.traineddata),還有其他的相關cube的檔案(XXX.cube.XXX)。

    所以初始化Tesseract時所帶的參數,
    若是設定為OEM_TESSERACT_CUBE_COMBINED,
    就會需要這些cube的檔案,如果你自己訓練的資料不包含這些項目的話,初始化就會失敗。

    你可以試著把Tesseract.OcrEngineMode設定為OEM_TESSERACT_ONLY,應該就可以了!

    回覆刪除
    回覆
    1. 原來只是這個問題 可以使用了 感謝您

      刪除
  9. 我想起來之前其實有嘗試改變OcrEngineMode 但不可行
    其原因是使用最新版本Tesseract 3.0.2
    其訓練出來的eng.traineddata組成成員沒有eng.pffmtable
    取而代之的是eng.shapetable
    應該是這點造成更改Mode也無法初始化
    使用3.0.1的traineddata才能用

    回覆刪除