2024年11月2日

利用 Python + EasyOCR 實現圖片轉文字辨識

最近剛好有個需求寫點小程式把圖片裡頭的文字抽出來,所以就稍微研究了一下 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)  

則可獲得結果:




沒有留言:

張貼留言

請注意,在較舊的文章留言並不會馬上出現在回應區!

Site Meter