在Tesseract的討論論壇中看到一篇文章,有人研究tesseract在文字高度在30~33pixl~內辨識率是最佳的。
本文就將來實作看看,拿出之前實驗用的OCR圖檔來跑跑看。
縮放與不縮放的圖片在tesseract OCR結果比較
import os
import pytesseract
import time
import numpy as np
from collections import Counter
import cv2
def obj_area(img):
num_labels, labels, stats, _ = cv2.connectedComponentsWithStats(img, connectivity=8)
components = []
ocr_components = []
if num_labels < 2: # 若全黑的就跳過
return None,None
for i in range(1, num_labels): # 跳過背景
x, y, w, h, area = stats[i]
components.append([x, y, w, h, area])
components.sort(key=lambda c: c[0]) # 按 x 座標排序
for state in components:
_,_,w,h,area = state
# ocr_components.append(f'{ocr}, 寬:{w}, 高 : {h} 面積:{area}')
ocr_components.append((w,h,area))
return ocr_components
def resize_img(img,ocr_h):
H,W = img.shape[:2]
target_height = 31
# 計算目標高度
target_ratio = target_height / ocr_h
if target_ratio > ocr_h :
resize_interpolation = cv2.INTER_CUBIC
else:
resize_interpolation = cv2.INTER_AREA
# 根據計算出的高度進行縮放
scaled_region = cv2.resize(img, (int(W*target_ratio), int(H*target_ratio)), interpolation = resize_interpolation)
return scaled_region
def main():
# 圖檔路徑
img_path = "圖片路徑"
# tesserac檔案路徑
pytesseract.pytesseract.tesseract_cmd = r"tesserac檔案路徑"
config = f'--oem 3 --psm 7'
# 讀取圖檔
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
labels = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# 計算OCR高度
h_res = obj_area(labels)
ocr_h = int(np.median([pos[1] for pos in h_res]))
print(f'原先ocr_h:{ocr_h}')
# 縮放圖片
image_resize = resize_img(labels,ocr_h)
# 計算縮放後的OCR高度
resize_h_res = obj_area(image_resize)
ocr_h_resize = int(np.median([pos[1] for pos in resize_h_res]))
print(f'縮放後的ocr_h:{ocr_h_resize}')
ocr_text = pytesseract.image_to_string(image_resize, lang="eng_Best", config=config)
print(ocr_text)
if __name__ == "__main__":
main()
原圖:錯誤率35%
縮放後 : 錯誤率40%
原圖:錯誤率10%
縮放後:錯誤率 6%
模型對於某些字體或者是大小會直接影響到辨識率,官方雖然說Best模型辨識率較佳,但在一些使用上的經驗來講,某些狀況則不一定是最佳,如這次實驗fast模型就好很多。
兩個模型在縮放後的結果也不盡相同,但在fast模型是有明顯提高辨識率的。