最近剛好有個需求寫點小程式把圖片裡頭的文字抽出來,所以就稍微研究了一下 OCR 的部份。
目前幾個常見的 OCR Library 包含 easyocr 以及 tesseract ,其中 tesseract 的速度比較快,但是我自己試用過後覺得中文辨識的成功率偏低,尤其當你來源的圖片背景和顏色比較雜的時候。 我自己覺得 tesseract 可能比較適合拿來辨識一些基礎版 CAPTCHA 的圖片。而 Easy OCR 不論是使用上還是成功率我都覺得高出許多。
1. 安裝
首先先建立一個 easyocr 專用的 pyenv 環境:
$ pyenv virtualenv easyocr
$ pyenv activate easyocr
然後透過 pip 來安裝它。
$ pip install easyocr
2. 使用
安裝好後把 easyocr import 進來就可以透過以下方式簡單的 initial 起來:
import easyocr
reader = easyocr.Reader(['ch_tra', 'en'], gpu = True)
以這邊的例子來說,是直接使用了官方提供的繁體中文模型以及英文模型,可以視需要導入不同的模型來使用,也可以訓練自己的模型。有顯卡的話 gpu 選項也建議打開,我自己是使用 NVIDIA 的卡,效率會好很多。
以此圖為例:
就可以用 readtext() 進行辨識:
>> result = reader.readtext('b82.jpg')
然後就會得到像是這樣的資料:
[([[np.int32(128), np.int32(403)],
[np.int32(445), np.int32(403)],
[np.int32(445), np.int32(487)],
[np.int32(128), np.int32(487)]],
'臺鐵竹中站',
np.float64(0.6208041320437083)),
([[np.int32(154), np.int32(474)],
[np.int32(255), np.int32(474)],
[np.int32(255), np.int32(519)],
[np.int32(154), np.int32(519)]],
'TRA',
np.float64(0.730491578578949)),
([[np.int32(273), np.int32(473)],
[np.int32(435), np.int32(473)],
[np.int32(435), np.int32(517)],
[np.int32(273), np.int32(517)]],
'Station',
np.float64(0.9904228637357921)),
......
其每筆資料的內容就分別是: 位置,辨識結果, probe 。
所以你就可以用來把辨識出的文字框出來:
>>> import cv2
>>> img = cv2.imread('b82.jpg')
>>> img = cv2.rectangle(img, result[0][0][0], result[0][0][2], (0,0,0), 3)
>>> cv2.imshow('image',img)
第一項位置的內容基本上就是 [左上,右上,右下,左下] 的座標:
probe 可以用來粗略推斷辨識結果的可用性。
如果你不在乎這些其他資料,只單純是想將文字資料辨識出來,那可以在 readtext 時加上 detail = 0
>>> reader.readtext('b82.jpg', detail=0)
['臺 鐵 竹 中 站 ', 'TRA', 'Station', '新 竹 科 學 園 區 ', 'Hsinchu Science Park', '`', '$', '', '']
此外如果想要只辨識某些特定的字元,也可以在 readtext() 時使用 allowlist ,最經典的例子大概就是車牌辨識,例如:
則:
import easyocr
import cv2
readeren = easyocr.Reader(['en'], gpu = True)
result = readeren.readtext('154924.jpg', allowlist='ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.')
img = cv2.imread('154924.jpg')
for rec in result:
img = cv2.rectangle(img, rec[0][0], rec[0][2], (0,255,0), 10)
img = cv2.putText(img, rec[1], rec[0][2], cv2.FONT_HERSHEY_SIMPLEX, 5, (0,255,0), 5, cv2.LINE_AA)
cv2.imshow('image',img)
則可獲得結果:
沒有留言:
張貼留言
請注意,在較舊的文章留言並不會馬上出現在回應區!