每日最新頭條.有趣資訊

如何構建識別圖像中字元的自動程序?一文解讀OCR與HTR

選自Medium

作者:Ajinkya Khalwadekar

機器之心編譯

參與:Panda、蛋醬

在機器學習和計算機視覺領域,光學字元識別(OCR)和手寫文本識別(HTR)長期以來都是人們研究的重要主題。本文將幫助計算機視覺愛好者大致了解如何對文檔圖像中的文本進行識別。

光學字元識別和手寫文本識別是人工智能領域裡非常經典的問題。OCR 很簡單,就是將文檔照片或場景照片轉換為機器編碼的文本;而 HTR 就是對手寫文本進行同樣的操作。作者在文章中將這個問題分解成了一組更小型的問題,並製作了如下的流程圖。

圖 1.1:應用流程圖

按文檔邊框裁剪圖像

在圖像處理中,通常需要對圖像進行預先編輯,以便獲得更好的表征。裁剪是圖像編輯中最常用的操作之一,這可以移除圖像中不需要的部分,也可以向圖像添加所需的特徵。

你可以使用 OpenCV 來輕鬆地找到圖像中文檔的邊緣,查找圖像中文檔邊緣的最佳方法是使用閾值圖像。OpenCV 提供了不同的閾值樣式,這是由其函數的第 4 個參數決定的。在這個函數中,第一個參數是源圖像,這應該是一張灰度圖像;第二個參數是用於分類像素值的閾值;第三個參數是 maxVal,這是當像素值超過(有時是低於)閾值時所要給出的值。

下面的代碼將能幫助你找到閾值圖像,然後確定文檔邊緣的輪廓,你可以將這些輪廓點與圖像邊緣進行比較,然後確定文檔的邊緣。

檢測和裁剪/分割文檔中的所有詞

在有約束的受控環境中進行詞檢測通常可以使用啟發式方法實現,比如利用梯度信息或者這樣的事實:文本通常會被分組成段落以及排列成直線的字元。但是,使用啟發式方法是存在缺陷的,圖像中很多不需要的區域也會被檢測為詞,所以我們可以使用 OpenCV 的 EAST(Efficient and Accurate Scene Text)檢測器。

可以參考 Adrian Rosebrock 寫的 EAST 檢測器相關文章:https://www.pyimagesearch.com/2018/08/20/opencv-text-detection-east-text-detector/

然後再根據 Tom Hoag 分享的方法對其進行改進:https://medium.com/@tomhoag/opencv-text-detection-548950e3494c

這種方法能以很高的準確度檢測出手寫文本以及機器列印的文本。檢測出圖像中的詞之後,再將它們裁剪出來並將它們全部保存下來。

預處理詞圖像

應該怎麽樣對圖像進行預處理?這完全取決於你接下來要做什麽。如果想要分類手寫的和機器列印的詞,需要所有圖像都處於灰度模式。為了將圖像轉換為灰度圖像,還需要使用 OpenCV:

這是手寫詞嗎?

這是一個分類問題:確定一張特定圖像中的詞是「手寫詞」還是「機打詞」。作者瀏覽了多篇文章和研究論文,發現支持向量機(SVM)是解決這一問題的最佳方案,然後使用了來自 sklearn 套裝軟體的 SVM 分類器來完成這一任務。

對於用於分類的數據集,作者提到了一個很好的手寫詞圖像有標注數據集 IAM:http://www.fki.inf.unibe.ch/databases/iam-handwriting-database

對於機器列印的詞圖像,作者收集了大約 2000 張詞圖像。下面是用於預測的特徵:

1. 平均像素強度

2. 像素強度的標準差

3. Otsu 閾值

4. 像素強度直方圖中局部最大值的數量

5. 屬於像素強度上面的四分之一的像素的百分比

6. 屬於像素強度下面的四分之一的像素的百分比

按照上面來看,所有特徵都與圖像的像素強度有關聯。下一個問題是:如何找到像素強度?

灰度圖像的像素值就是像素的強度,同樣也可以使用 OpenCV 和數學運算來完成這一任務。

使用 TensorFlow 的 HTR

這是本文所有問題中最具有挑戰性的問題。在嘗試了不同的解決方案之後(包括在手寫字符數據集上重新訓練 Tesseract),結果顯示 Harald Scheidl 這篇文章的方法最佳:https://towardsdatascience.com/build-a-handwritten-text-recognition-system-using-tensorflow-2326a3487cd5

作者使用了類似的方法,不過做了一些小修改,在這裡使用了神經網絡,由 5 個卷積神經網絡(CNN)層、2 個循環神經網絡(RNN)層和 1 個連接主義時間分類(CTC)層構成。用於訓練這個神經網絡的數據集是 IAM 數據集,但你也可以使用任何有標注的詞圖像數據集。

圖 1.2:來自 Herald Scheidl 文章的示意圖

CNN 層的輸入是大小為 128×32 的灰度值圖像。CNN 層的輸出是一個序列,其包含 32 項,其中每一項都有 256 個特徵。這些特徵再進一步由 RNN 層處理,但是,某些特徵已經表現出了與輸入圖像的特定高層面性質的高度相關性。

圖 1.3:來自 Herald Scheidl 的文章的示意圖

圖 1.3 展示了處理一張包含文本「little」的圖像時,可視化的 RNN 輸出矩陣。最上面的圖表中的矩陣包含了字元的分數,這些字元中的最後一項(第 80 個)是一個 CTC 空白標簽。其它矩陣項,從上到下分別對應於如下字元:!」#&』()*+,-./0123456789:;?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz

可以看到,大多數時間裡,被預測的字元都剛好出現在它們在圖像中的位置處(比如,你可以比較看看圖像與圖表中 i 的位置。只有最後一個字元 e 沒有對齊。但這其實沒有問題,因為 CTC 操作是無分割的,而且不在乎絕對位置。最下面的圖表展示了字元 l、i、t、e 和 CTC 空白標簽的分數,該文本可以輕鬆地被解碼:我們只需要從每個時間步驟取出最可能的字元即可,這會構成所謂的最佳路徑,然後我們丟棄重複的字元,最後丟棄所有空白,得到:「l—-ii—t-t—l-…-e」「l—-i—t-t—l-…-e」「little」。

更多有關如何實現這一方法的細節信息,請參看 Herald Scheidl 的文章。

Tesseract(OCR)

Tesseract 是目前最好的用於機器列印字元識別的開源 OCR 工具。Tesseract 支持 Unicode(UTF-8)字元集,可以識別超過 100 種語言,還包含多種輸出支持,比如純文本、PDF、TSV 等。但是為了得到更好的 OCR 結果,還必須提升提供給 Tesseract 的圖像的質量。

注意,在執行實際的 OCR 之前,Tesseract 會在內部執行多種不同的圖像處理操作(使用 Leptonica 庫)。通常它表現不錯,但在某些情況下的效果卻不夠好,導致準確度顯著下降。

在將圖像傳遞給 Tesseract 之前,可以嘗試以下圖像處理技術,但具體使用哪些技術取決於你想要讀取的圖像:

1. 反轉圖像

2. 重新縮放

3. 二值化

4. 移除噪聲

5. 旋轉/調整傾斜角度

6. 移除邊緣

所有這些操作都可以使用 OpenCV 或通過 Python 使用 numpy 實現。

簡單總結一下,本文介紹了與 OCR 和 HTR 相關的一些問題和可能的解決方案。如果你想要真正理解,一定要親自動手實現它們看看。

本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。

------------------------------------------------

獲得更多的PTT最新消息
按讚加入粉絲團