Tesseract-OCR 介紹
Tesseract的OCR引擎最先由HP實驗室於1985年開始研發,至1995年時已經成為OCR業內最準確的三款識別引擎之一。然而,HP不久便決定放棄OCR業務,Tesseract也從此塵封。
數年以後,HP意識到,與其將Tesseract束之高閣,不如貢獻給開源軟件業,讓其重煥新生--2005年,Tesseract由美國內華達州信息技術研究所獲得,並求諸於Google對Tesseract進行改進、消除Bug、優化工作。
Tesseract目前已作為開源項目發佈在Google Project,其最新版本3.0已經支持中文OCR,並提供了一個命令行工具。
主要使用在辨識掃描文件/圖片的文字,包含契約、發票等等,能夠輕鬆地減少需要人力的工作,例如像 RPA(Robotic Process Automation)類型的專案可能都會使用到。
步驟一:安裝 Tesseract-OCR
個人電腦是使用 MAC 進行安裝,所以如果是 Windows 系統的小夥伴們可能就要另找其他教學來安裝了!在進行之前,首先先介紹一下會用到的幾個網站以及資源。
網站一:https://www.jianshu.com/p/5f847d8089ce
這個網站是我主要用來參考安裝以及訓練的,通篇文章也會以這個網站的來源解說為主,所以如果我這邊講的不夠仔細,建議大家可以直接到這個網站進行使用(但當然我會以自己的使用心得多家詳細解釋遇到的問題以及寫法)
網站二:https://github.com/tesseract-ocr/tesseract/wiki
這是官方維運 Tesseract-OCR 的網站,有詳細指令以及其他更細節的說明,對於細節有興趣的人可以再去裡面看更細的部分,也有部分指令和內容取自此網站的內容
以下是個人按照後面流程安裝後的版本,本篇通文都以這個版本為主進行
開啟 terminal, 輸入 tesseract -v, 下面為顯示的版本資訊
tesseract 3.05.02
leptonica-1.76.0
libjpeg 9c : libpng 1.6.35 : libtiff 4.0.9 : zlib 1.2.11
透過 Homebrew(不清楚的google就可以找到安裝資訊) 安裝 Tesseract-OCR:
1.開啟 Terminal
2.輸入
brew install tesseract --HEAD --with-training-tools
— HEAD 不加的話為默認安裝3.05
— with-training-tools 一定要加這個 Tool,才能做模型訓練P.S. 目前使用訓練版本為3.x,使用4.x版本的訓練方法會有異,等之後測試了 4.x版本再來更新
3. 到此網站下載中文的語言辨識包
https://github.com/tesseract-ocr/tessdata_best
— chi_sim.traineddata -> 簡體中文包
— chi_tra.traineddata ->繁體中文包4. 將語言辨識包放到以下路徑
語言包路徑:
/usr/local/Cellar/tesseract/3.05.02[版本號]/share/tessdata
步驟二:圖片預先處理
安裝完畢之後,接著我們要來針對圖片做一些處理,基本上在做OCR辨識之前,我們要把圖片的雜訊(Noise),也就是會影像模型判斷的相關的錯誤去除,這邊介紹幾個由 Tesseract 官方所歸納的方法來解決圖片問題。
https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
英文原文細節可參考上述網站(Tesseract-OCR Wiki),以下圖片以及中文均引用自上述 Tesseract -OCR 官方 Wiki
而在說明圖片預先處理之前,簡單說明一下圖片辨識的原理。
通常來說會針對每個Image都有不同的標記,而我們要辨識的物件本身也有特定的標記(Feature Detector),所以當進行辨識的時候,Feature Detector 會去掃描 Input Image 上的所有標記看符不符合,符合的話代表有辨識出來,便會產生該結果。
下圖代表要去找 Feature Detector ,所以4分的那一塊就代表辨識到要的部分,因為有符合 Feature Detector 含有 1 的數字。(把Feature Detector 的中心擺在 Input Image 的第五行第三列。)
- Binarisation:將左方圖片透過 Image Processing 方法處理後變為右邊,要注意的是,可能會出現如右圖的大片雜質出現的情形發生。
這邊介紹使用 OpenCV 套件來處理圖片 ->https://ppt.cc/fbuBex
個人使用 Python 進行測試,所以使用 opencv-python 這個套件來運用 OpenCV 的 lib,因為示範的 Code 都有在上列網站上,就不再贅述了
2. Noise Removal:透過 Image Processing 方法處理圖片後,可能會出現如圖中的大片雜質出現的情形發生,要注意是否圖片有這種情形
3. Rotation / Deskewing:將掃描文件有歪斜的修正成正常的角度。
4. Borders:有些掃描文件甚至會把邊界給納入,這在辨識上會是另一個造成辨識效果不彰的一個Noise
5. Tesseract在DPI為至少為300 DPI的圖像上效果最佳,所以需要考慮提高圖片的DPI,一般圖片默認的都是72 。如果要進行轉換的話,可以透過執行以下指令
代表要批次的轉換在 path路徑下 img-名稱開頭的 jpg檔案
convert ‘*.jpg’ -density 300 ~/path/img-%d.jpg
步驟三:指令測試階段
這一步驟先帶大家簡單的介紹一下 Tesseract 的辨識指令,所以可以比較原本官方現有的訓練集跟自己的訓練集是否有比較好
來源參考:https://blog.csdn.net/u010670689/article/details/78374623
- 列出目前存在可使用的語言庫
tesseract — list-langs
2. 指定訓練集進行辨識(看訓練集的名稱,通常英文是eng,簡體中文 chi_sim,繁體中文 chi_tra)
tesseract -l [語言庫] [辨識的圖片] [輸出檔名]
3. 指定辨識方式:因應不同的圖片必須選擇對應的 -psm 對應方式,否則有可能辨識會不夠清楚。
tesseract -l [語言庫] [辨識的圖片] [輸出檔名] -psm [數字]
數字解釋
0 Orientation and script detection (OSD) only.
1 Automatic page segmentation with OSD.
2 Automatic page segmentation, but no OSD, or OCR.
3 Fully automatic page segmentation, but no OSD. (Default)
4 Assume a single column of text of variable sizes.
5 Assume a single uniform block of vertically aligned text.
6 Assume a single uniform block of text.
7 Treat the image as a single text line.
8 Treat the image as a single word.
9 Treat the image as a single word in a circle.
10 Treat the image as a single character.
(1) 舉例一:辨識 test1.png 圖片,輸入下面指令即可產出 test1 辨識結果:
tesseract -l eng test1.png test1
test1 辨識結果
vuxsc
FUEL
NETIAIID cm:
931.00
115.95-8161
601.56
(2) 如果以 1234.png 圖片輸入的話,最後會得到 Empty Page
1234.png 輸入指令
tesseract -l eng 1234.png 1234
1234.png 辨識結果
Tesseract Open Source OCR Engine v3.05.02 with Leptonica
Empty page!!
Empty page!!
但如果是加入 psm ,即可產生結果
1234.png 輸入指令
tesseract -l eng 1234.png 1234 -psm 6
1234.png 辨識結果
一二三四
一二三四
步驟四:訓練階段
訓練之前,我們要先下載一個專門的 Tool : jTessBoxEdtor,這個軟體有個GUI介面讓我們直接操作實現訓練的情形
下載網址,基本上用最新版本就可以了,筆者使用的是 v1.8.0版本
https://sourceforge.net/projects/vietocr/files/jTessBoxEditor/
(一)合併tif文件
這裡把要標記辨識的圖片選擇一起進行,基本上不限制數量,但依照參考的文獻還有自己的經驗是就100張圖片以內一組。
這邊說一下命名的規則
[lang].[fontname].exp[num].tif (tif為自動加的副檔名)
- lang 就是語言辨識集的名字,如果tiff都取這個名字,之後可以合併成同一個辨識的模型,所以這個名字要好好的取
- fontname 就是辨識的字體,所以最好的情況是知道自己要辨識的字體是哪一個
- exp[num],exp 似乎是訓練上官方指定的,但試驗過好像都沒差,重點在於要更動不同的數字來區別自己訓練的資料集,之後都可以合併一起
(二)生成 .box 文件
接著 cd 路徑回到生成tiff的地方,要準備生成 .box 文件才能開始進行辨識建立模型。輸入指令
記得將下面自己生成的 tif 改成自己名字,另外 [] 內的建議輸入,筆者認定是應該會把辨識的基礎加入,行程模型開始訓練的基底。這個問題我會在最後面進行探討還有個人想法。
tesseract TrainTest.Arial.exp1.tif TrainTest.Arial.exp1 [-l chi_tra -psm 6] batch.nochop makebox
輸入上述指令後會生成 .box 文件,接著開始進入手動標記的動作
(三)手動標記
首先點擊Open部分,把剛剛訓練的 tiff 在這個軟體打開。
接著可以看到目前軟體當中辨識出來的部分,我們的任務就是要把一個字元準確的框起來,就達到訓練模型的目的,所以像目前「你」這個字眼被系統拆成兩個字元辨識就是不對的,因此我們要透過紅色框起來的Merge, Split, Insert, Delete 操作。
1.Merge
當點擊左方欄位任一列時候,就會對應到右方的藍色框框,表示你正在對哪個做操作,那麼當一口氣選擇兩個的時候Shift + 滑鼠左鍵),會發現有兩個藍色框框反紅,此時就可以使用 Merge ,把這兩個辨識框框合起來,我們要的就是辨識「你」這個中文字,所以應該只有一個藍色框框才對。
2. Split
這個按鈕跟 Merge 是相反, Merge 是把兩個合成一個,這個就是把原本的一個框框,「平均一半」切成兩個。
3. Insert
Insert 使用的時候,一定要先選擇一個藍色框框,點擊 Insert 之後,會多出一個藍色框框貼在後面,大小會跟選擇的藍色框框一樣。
4. Delete
這個就是刪除點擊的藍色框框,就不贅述了
5.標記流程
這邊大概介紹一下平常我是怎麼做標記比較快速。
(1) 從左上角文字開始慢慢一個一個開始進行標記
(2) 善用 Merge, Split , Insert , Delete 四個按鈕加快速度
(3) 當要針對新的文字增加藍色框框的時候,建議選擇最相近的文字使用 Insert 新增
(4) 接著建議使用右上角的 X:水平移動框框, Y:垂直移動框框, W:水平擴大框框, H:垂直擴大框框
(5) 在 Character 的表格上,打上正確的文字標註
(6) 記得時不時就按一下左上角的Save,不然當機重新標記肯定會欲哭無淚………
(四)生成 .train 文件
當把 tif 檔案內的文字都標註完畢之後,就可以開始輸入下面的指令生成 .train 文件
記得把 tif 的檔案改成自己一開始命名的
-l, -psm 一樣看你用哪種語言包,以及psm的指令進行辨識行為的更動
tesseract TrainTest.Arial.exp1.tif TrainTest.Arial.exp1 -l chi_tra -psm 6 nobatch box.train
會在該目錄下生成 .tr 的文件
(五)生成 .unicharset文件
輸入以下指令,生成 .unicharset 文件
unicharset_extractor TrainTest.Arial.exp1.box
(五)定義並生成 font_properties文件
文件內容為
字體 0 0 0 0 0
字體:代表圖片中的文字字體
italic:是否為斜體(是的話為1, 不是的話為0)
bold:是否為粗體 (是的話為1, 不是的話為0)
fixed:是否為等寬字體(是的話為1, 不是的話為0)
serif:是否為襯線體 (是的話為1, 不是的話為0)
fraktur:是否為德文尖角體(是的話為1, 不是的話為0)
輸入以下命令生成 font_properties 文件
下面一樣依照個人的需求進行修改
echo Arial 0 0 0 0 0 >font_properties
(六)Clustering
官方提供 shapeclustering 、 mftraining 和 cntraining 三個步驟,但因為官方文件有說第一個屬於印度語生成才需要使用,因此就不使用。
mftraining -F font_properties -U unicharset -O TrainTest.unicharset TrainTest.Arial.exp1.tr
cntraining TrainTest.Arial.exp1.tr
(七)合併文件
接著要把現在生成的shapetable,normproto,inttemp,pffmtable,用lang在前方重新命名
例如 shapetable 我改成 TrainTest.shapetable,以此類推
然後輸入以下指令進行合併
記得把 lang 改成自己的
combine_tessdata TrainTest.
接著把生成 TrainTest.traineddata 放進去語言包的路徑
/usr/local/Cellar/tesseract/3.05.02[版本號]/share/tessdata
接著輸入指令,查看語言包有沒有放到 Tesseract 的語言包
tesseract — list-langs
步驟五:測試訓練文件
接著輸入辨識的指令,比較一下原本的辨識結果跟特地訓練後的結果
原本的辨識結果(以 Chi_tra的語言包進行辨識)
/午矸以蠢﹛ˍ
用新的訓練集來辨識(以TrainTest的語言包進行辨識)
你你可以的
好的,可以看到訓練基本上是有結果的,接著要講述一下其他的心得
(一)提高準確度
第一種方式就是用原本命名的訓練方式,把exp[num]往上加,記得把之前的.box , .tif 檔案留下來,這樣才能跟之後的訓練在一起。
第二種我嘗試過把原本訓練的 .box , .tif 複製一份,改名exp[num]往上加,後來發現這樣的效果有限,只會針對原本有辨識到文字的部分有反應。
意思是說,如果你仔細看上一步驟(四)生成 .train 文件的命令列跑的過程,有發現下面 FAIL 字樣,代表該軟體無法辨識該圖片區域的文字,就算你再重新 Train 也一樣,所以如果遇到一個文字你怎麼重新訓練都無法,代表該區域你始終就是不能辨識,只能透過截圖、移動圖形的範圍改變原本圖形的排列,然後再重新辨識,就能夠成功。
查過 Stack Overflow ,有人提到這似乎是 Tesseract 3.x版本的核心漏洞,感覺應該是無解,筆者也是了蠻多方法,但就只能夠透過改變圖片原有的形式才能進行辨識,也許是有特殊像素或者某種排列讓軟體無法進行辨識。
(二)Pytesseract
筆者在使用的時候適用Python語言,所以找了 Lib 透過 Python 使用 Tesseract 的功能。
上面的 Github 敘述的蠻詳細怎麼使用,這樣就不用一直都要打開命令列去進行辨識結果的測試了。
(三)4.X版本 Tesseact
因為針對 4.X 版本的 Tesseract 解說蠻少的,也只透過同事了解說,運用原本的語言包辨識效果基本上就提升了很多,但是關於訓練的部分還要再研究,如果之後有使用心得會繼續再更新下去的。