[ 實用心得 ] Tesseract-OCR

凱稱研究室
17 min readNov 21, 2018
「OCR」的圖片搜尋結果
OCR,將文件或圖片辨識,包含手寫文字,轉成可編輯文字

因為工作上的關係,接觸到了 Tesseract 由 Google 目前正在維護的開放原始碼專案,本文單純紀錄個人訓練實用上的心得,不細究探討 Tesseract 的相關架構和原理,會結合在網上找到的資料進行實用上的解說。如果也有讀者有相關經驗可以共同交流,誠摯的歡迎能互相交換想法。

Tesseract-OCR 介紹

Tesseract 發展史(來源:https://www.jianshu.com/p/726d4ece4031)

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 上的所有標記看符不符合,符合的話代表有辨識出來,便會產生該結果。

引用自 Udemy “ Deep Learning A-Z™: Hands-On Artificial Neural Networks”

下圖代表要去找 Feature Detector ,所以4分的那一塊就代表辨識到要的部分,因為有符合 Feature Detector 含有 1 的數字。(把Feature Detector 的中心擺在 Input Image 的第五行第三列。)

引用自 Udemy “ Deep Learning A-Z™: Hands-On Artificial Neural Networks”
  1. 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

  1. 列出目前存在可使用的語言庫

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.png

test1 辨識結果

vuxsc
FUEL
NET

IAIID 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 辨識結果

一二三四

一二三四

1234.png

步驟四:訓練階段

訓練之前,我們要先下載一個專門的 Tool : jTessBoxEdtor,這個軟體有個GUI介面讓我們直接操作實現訓練的情形

下載網址,基本上用最新版本就可以了,筆者使用的是 v1.8.0版本

https://sourceforge.net/projects/vietocr/files/jTessBoxEditor/

(一)合併tif文件

這裡把要標記辨識的圖片選擇一起進行,基本上不限制數量,但依照參考的文獻還有自己的經驗是就100張圖片以內一組。

1. 首先打開軟體之後,選擇 Tools -> Merge TIFF (如此才能開始進行訓練)
2. 選擇要訓練辨識的圖片(這邊筆者只有一張,可選擇多張)
3. 進行命名

這邊說一下命名的規則

[lang].[fontname].exp[num].tif (tif為自動加的副檔名)

  1. lang 就是語言辨識集的名字,如果tiff都取這個名字,之後可以合併成同一個辨識的模型,所以這個名字要好好的取
  2. fontname 就是辨識的字體,所以最好的情況是知道自己要辨識的字體是哪一個
  3. exp[num],exp 似乎是訓練上官方指定的,但試驗過好像都沒差,重點在於要更動不同的數字來區別自己訓練的資料集,之後都可以合併一起
4.接著會看到說 TIFF 完成啦

(二)生成 .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 ,把這兩個辨識框框合起來,我們要的就是辨識「你」這個中文字,所以應該只有一個藍色框框才對。

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.

Combine 的命令列

接著把生成 TrainTest.traineddata 放進去語言包的路徑

/usr/local/Cellar/tesseract/3.05.02[版本號]/share/tessdata

接著輸入指令,查看語言包有沒有放到 Tesseract 的語言包

tesseract — list-langs

顯示出剛剛訓練的文件 TrainTest

步驟五:測試訓練文件

接著輸入辨識的指令,比較一下原本的辨識結果跟特地訓練後的結果

原本的辨識結果(以 Chi_tra的語言包進行辨識)

/午矸以蠢﹛ˍ

用新的訓練集來辨識(以TrainTest的語言包進行辨識)

你你可以的

好的,可以看到訓練基本上是有結果的,接著要講述一下其他的心得

(一)提高準確度

第一種方式就是用原本命名的訓練方式,把exp[num]往上加,記得把之前的.box , .tif 檔案留下來,這樣才能跟之後的訓練在一起。

第二種我嘗試過把原本訓練的 .box , .tif 複製一份,改名exp[num]往上加,後來發現這樣的效果有限,只會針對原本有辨識到文字的部分有反應。

意思是說,如果你仔細看上一步驟(四)生成 .train 文件的命令列跑的過程,有發現下面 FAIL 字樣,代表該軟體無法辨識該圖片區域的文字,就算你再重新 Train 也一樣,所以如果遇到一個文字你怎麼重新訓練都無法,代表該區域你始終就是不能辨識,只能透過截圖、移動圖形的範圍改變原本圖形的排列,然後再重新辨識,就能夠成功。

FAIL 的命令列

查過 Stack Overflow ,有人提到這似乎是 Tesseract 3.x版本的核心漏洞,感覺應該是無解,筆者也是了蠻多方法,但就只能夠透過改變圖片原有的形式才能進行辨識,也許是有特殊像素或者某種排列讓軟體無法進行辨識。

(二)Pytesseract

筆者在使用的時候適用Python語言,所以找了 Lib 透過 Python 使用 Tesseract 的功能。

上面的 Github 敘述的蠻詳細怎麼使用,這樣就不用一直都要打開命令列去進行辨識結果的測試了。

(三)4.X版本 Tesseact

因為針對 4.X 版本的 Tesseract 解說蠻少的,也只透過同事了解說,運用原本的語言包辨識效果基本上就提升了很多,但是關於訓練的部分還要再研究,如果之後有使用心得會繼續再更新下去的。

--

--

凱稱研究室

心理學/情緒管理的業餘研究者👨‍🔬 專案管理/敏捷方法/Scrum 研究者🏈 linktr.ee/kaichen9527