OCR(Optical Character Recognition),譯為光學字元識別,是指通過掃描等光學輸入方式將各種票據、報刊、書籍、文稿及其它印刷品的文字轉化為影像資訊,再利用文字識別技術將影像資訊轉化為可以使用的計算機輸入技術。
在不久前的首屆“中國人工智慧·多媒體資訊識別技術競賽”中,百度一舉斬獲印刷文字OCR、人臉識別和地標識別三項任務中的A級證照,其中印刷文字OCR的成績更是摘得冠軍,且因成績顯著優於其他參賽團隊,成為該任務94支參賽隊伍中唯一獲得A級證照的單位。
在OCR技術出現之前,要把大量的卡證牌照、票據表單、紙質文件上的文字資訊錄入電腦,只能依賴人工,效率低下,而且極易出錯。
隨著OCR技術的成熟,“人工數字化”的現狀被打破,OCR自動化識別代替了人工錄入,大大節約了人力成本,有效提升了業務效率。
OCR技術的應用場景非常廣泛:
(1)拍照/截圖識別
使用OCR技術,實現拍照文字識別、相簿圖片文字識別和截圖文字識別,可應用於搜尋、書摘、筆記、翻譯等移動應用中,方便使用者進行文字的提取或錄入,有效提升產品易用性和使用者使用體驗。
識別結果:
(2)內容稽核與監管
使用OCR技術,實現對影像中文字內容的提取,結合文字稽核技術識別違規內容,提示相應風險,協助進行違規處理,可應用於電商廣告稽核、輿情監管等場景,幫助使用者有效規避業務風險。
(圖片來自網路)
識別結果:
(3)視訊內容分析
使用OCR技術,實現對視訊中的字幕、標題、彈幕等文字內容的檢測和識別,並根據文字位置判斷文字型別,可應用於視訊分類和標籤提取、視訊內容稽核、營銷分析等場景,有效降低人力成本,控制業務風險。
圖片來自網路
識別結果:
(4)紙質文件電子化
使用OCR技術,實現對各類醫療單據、金融財稅票據、法律卷宗等紙質文件的識別,並返回文字在圖片中的位置資訊以便於進行比對、結構化等處理,可滿足醫療、金融、政務、法務、教育等行業文件快速錄入、存檔和檢索的需求,有效降低企業人力成本,提高資訊錄入效率。
(注:以上識別效果來源百度AI開放平臺,感興趣的使用者可以線上體驗)
2.OCR技術原理
從整體上來說,OCR技術可以分為影像處理和文字識別兩大階段:
影像處理階段:包含影像輸入、影像預處理、版面分析、字元切割等子步驟。
文字識別階段:包含特徵提取、字元識別、版面恢復、後處理等子步驟。
流程圖如下:
【文字檢測】
影像輸入:讀取不同格式的影像檔案。
影像預處理:包含灰度化、二值化、影像降噪、傾斜矯正等預處理步驟。
版面分析:針對左右兩欄等特殊排版,進行版面分析並劃分段落。
字元切割:對影像中的文字進行字元級的切割,尤其注意字元粘連等問題。
【文字識別】
特徵提取:對字元影像提取關鍵特徵並降維,用於後續的字元識別演算法。
字元識別:依據特徵向量,基於模版匹配分類法或深度神經網路分類法,識別出字元。
版面恢復:識別原文件的排版,按照原排版的格式將識別結果輸出。
後處理:引入語言模型或人工檢查,修正“分”和“兮”等形近字。
從整體上來看,OCR 的步驟繁多,涉及到的演算法也很複雜。針對每一個步驟的每一個演算法,都有單獨的研究論文。如果從零開始做 OCR,將是一個十分浩大的工程。飛槳先從一個入門的實驗開始,教您如何藉助飛槳快速實現OCR功能。
3.1 任務介紹
本次實驗的任務是最簡單的任務:識別圖片中單行英文字元,從這個簡單的任務開始,主要是熟悉OCR的關鍵技術點,實際上OCR的技術有很多,一般都是文字檢測+文字識別,比如經典的CRNN+CTC、Seq2seq+Attention,考慮到文字檢測涉及到的內容比較複雜,我們主要以CTC(Connectionist Temporal Classification) 模型為例,前提假設文字已經檢測到,限定在一個比較小的行內,然後如何來進行文字識別部分的內容。
編碼部分,首先採用卷積將圖片轉為特徵圖, 然後再將特徵圖轉為序列,通過雙向GRU學習到序列特徵。
損失函式在訓練過程選用的損失函式為CTC loss,這也是CTC演算法稱呼的來源。預測階段採用的是貪婪策略和CTC解碼策略。評估指標是樣本級別的錯誤率。
3.2 資料示例
資料的下載和簡單預處理都在data_reader.py中實現。
資料示例:
我們使用的訓練和測試資料如下圖所示,每張圖片包含單行不定長的英文字串,這些圖片都是經過檢測演算法進行預框選處理的。
在訓練集中,每張圖片對應的label是漢字在詞典中的索引。圖1 對應的label如下所示:
80,84,68,82,83,72,78,77,68,67
在上邊這個label中,80 表示字元Q的索引,67 表示英文字元D的索引。
3.3 資料準備
(1)訓練集
我們需要把所有參與訓練的圖片放入同一個資料夾,暫且記為train_images。然後用一個list檔案存放每張圖片的資訊,包括圖片大小、圖片名稱和對應的label,這裡暫記該list檔案為train_list,其格式如下所示:
185 48 00508_0215.jpg 7740,5332,2369,3201,4162
48 48 00197_1893.jpg 6569
338 48 00007_0219.jpg 4590,4788,3015,1994,3402,999,4553
150 48 00107_4517.jpg 5936,3382,1437,3382
...
157 48 00387_0622.jpg 2397,1707,5919,1278
檔案train_list,上述檔案中的每一行表示一張圖片,每行被空格分為四列,前兩列分別表示圖片的寬和高,第三列表示圖片的名稱,第四列表示該圖片對應的sequence label。最終我們應有以下類似檔案結構:
|-train_data
|- train_list
|- train_imags
|- 00508_0215.jpg
|- 00197_1893.jpg
|- 00007_0219.jpg
| ...
在訓練時,我們通過選項--train_images 和 --train_list 分別設定準備好的train_images 和train_list。
在data_reader.py中,會按照使用者設定的DATA_SHAPE調整訓練資料的高度。使用者可以根據自己準備的訓練資料,設定合適的DATA_SHAPE。如果使用預設的示例資料,則使用預設的DATA_SHAPE即可。
注:如果--train_images 和 --train_list都未設定或設定為None, data_reader.py會自動下載使用示例資料,並將其快取到$HOME/.cache/paddle/dataset/ctc_data/data/ 路徑下。
(2)測試集和評估集
測試集、評估集的準備方式與訓練集相同。在訓練階段,測試集的路徑通過train.py的選項--test_images和 --test_list 來設定。在評估時,評估集的路徑通過eval.py的選項--input_images_dir 和--input_images_list 來設定。
在data_reader.py中,會按照使用者設定的DATA_SHAPE調整測試影像的高度,所以測試影像可以有不同高度。但是,DATA_SHAPE需要和訓練模型時保持嚴格一致。
(3)待預測資料集
預測支援三種形式的輸入:
第一種:設定--input_images_dir和--input_images_list, 與訓練集類似, 只不過list檔案中的最後一列可以放任意佔位字元或字串,如下所示:
185 48 00508_0215.jpg s
48 48 00197_1893.jpg s
338 48 00007_0219.jpg s
...
第二種:僅設定--input_images_list, 其中list檔案中只需放圖片的完整路徑,如下所示:
data/test_images/00000.jpg
data/test_images/00001.jpg
data/test_images/00003.jpg
第三種:從stdin讀入一張圖片的path,然後進行一次inference.
在data_reader.py中,會按照使用者設定的DATA_SHAPE調整預測影像的高度,所以預測影像可以有不同高度。但是,DATA_SHAPE需要和訓練模型時保持嚴格一致。
3.4 模型訓練
使用預設資料在GPU單卡上訓練:
env CUDA_VISIBLE_DEVICES=0python train.py
使用預設資料在CPU上訓練:
env python train.py--use_gpu False --parallel=False
使用預設資料在GPU多卡上訓練:
env CUDA_VISIBLE_DEVICES=0,1,2,3 python train.py --parallel=True
預設模型使用的是CTC model,執行python train.py --help可檢視更多使用方式和引數詳細說明。
下圖為使用預設引數在預設資料集上訓練CTC model的收斂曲線,其中橫座標軸為訓練迭代次數,縱軸為樣本級錯誤率。其中,藍線為訓練集上的樣本錯誤率,紅線為測試集上的樣本錯誤率。測試集上最低錯誤率為22.0%。
3.5 模型測試
通過以下命令呼叫評估指令碼用指定資料集對模型進行評估:
env CUDA_VISIBLE_DEVICES=0 python eval.py \
--model_path="./models/model_0" \
--input_images_dir="./eval_data/images/" \
--input_images_list="./eval_data/eval_list"
執行python train.py --help可檢視引數詳細說明。
3.6 模型預測
從標準輸入讀取一張圖片的路徑,並對齊進行預測:
env CUDA_VISIBLE_DEVICES=0 python infer.py \
--model_path="models/model_00044_15000"
執行上述命令進行預測的效果如下:
----------- Configuration Arguments -----------
use_gpu: True
input_images_dir: None
input_images_list: None
model_path: /home/work/models/fluid/ocr_recognition/models/model_00052_15000
------------------------------------------------
Init model from: ./models/model_00052_15000.
Please input the path of image: ./test_images/00001_0060.jpg
result: [3298 2371 4233 6514 2378 3298 2363]
Please input the path of image: ./test_images/00001_0429.jpg
result: [2067 2067 8187 8477 5027 7191 2431 1462]
從檔案中批量讀取圖片路徑,並對其進行預測:
env CUDA_VISIBLE_DEVICES=0 python infer.py \
--model_path="models/model_00044_15000" \
--input_images_list="data/test.list"
3.7 開源預訓練模型
飛槳提供的經典的CTC 模型作為 OCR預訓練模型,開發者們可以直接下載使用。
CTC model 下載地址:
https://paddle-ocr-models.bj.bcebos.com/ocr_ctc.zip
注:在本章到示例中,均可通過修改CUDA_VISIBLE_DEVICES改變當前任務使用的顯示卡號。
特別說明:
以上就是經典OCR演算法在飛槳的實現過程,我們也可以看到,這個評測下的資料集,一方面數量不是特別多,另一方面識別難度其實是比較大的(包含不規則的文字,背景噪聲,嚴重的干擾等)。實際使用中,在一些比較受限的典型場景下,如果有豐富的訓練資料集,而且資料集比較簡單規整的情況下,實際效果會明顯改善的,有興趣的開發者可以自行嘗試。