2024-06-01|閱讀時間 ‧ 約 37 分鐘

[OCR][Python]測試tesseract與easyOCR誰比較準跟快

平時都在用tesseract來辨識OCR的部分,在網路上也常常聽說easyOCR比tesseract好用,就拿之前測試的OCR素材來比較看看囉。

以下輸入同樣圖片直接測試,並非絕對誰就比較準,只單純測試數字含英文的部分。

圖片素材就是15碼(英文加數字),檔名為OCR正確結果

保密原則,只好模糊掉數字跟英文



Tesseract 測試結果


Easy OCR 測試結果


Tesseract 程式範例

輸入的圖片檔名,OCR_數字為正確的OCR

讀圖辨識結果與檔名比較,得知誤判率

import os
import pytesseract
from PIL import Image
import re
import time
import numpy as np
from collections import Counter
import cv2

def find_errors(ocr_results, file_names):
error_details = []

for ocr, file_name in zip(ocr_results, file_names):
if ocr != file_name:
error_positions = [(i, a, b) for i, (a, b) in enumerate(zip(ocr, file_name)) if a != b]
error_details.append({"ocr": ocr, "file_name": file_name, "error_positions": error_positions})

return error_details

def rename_images():
res_str = 0
ocr_results = [] # 你的OCR結果清單
file_names = [] # 你的檔案名稱清單
all_time = 0
all_count = 0
'''
Change File Name -> OCR.Png
'''
folder_path = "D:/SaveImg/PSN/20240531"
valid_extensions = [".jpg", ".png", ".jpeg"]

pytesseract.pytesseract.tesseract_cmd = r"tesseract路徑"
config = f'--oem 3 --psm 7'
image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and any(f.lower().endswith(ext) for ext in valid_extensions)]
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and f.lower().endswith(".png")]

for i, (image_file, file_1) in enumerate(zip(image_files, files)):

_, extension = os.path.splitext(image_file)
original_path = os.path.join(folder_path, image_file)
file = file_1.split('_')[0]
# 使用 pytesseract 讀取文字
try:
start_time = time.time()
img = cv2.imread(original_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
labels = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
ocr_text = pytesseract.image_to_string(labels, lang="eng", config=config)
print(ocr_text)
except Exception as e:
print(f"Error reading text from {image_file}: {e}")
continue

ocr_text = ocr_text.strip()
# print(f'辨識到的OCR:{ocr_text}')
ocr_results.append(ocr_text) # 你的OCR結果清單
file_names.append(file) # 你的檔案名稱清單
if ocr_text == file:
res_str += 1

end_time = time.time()
elapsed_time = end_time - start_time
all_time += elapsed_time
print(f"處理 第{i} 張圖片共花費 {elapsed_time:.2f} 秒")

print(f'準確率:{(res_str/(i + 1) )*100}%,總共測試了{i + 1}張,誤判{((i + 1)-res_str)}張')

error_details = find_errors(ocr_results, file_names)
print("錯誤字母詳細資訊:")
for error in error_details:
print(f"OCR: {error['ocr']}, 檔案名稱: {error['file_name']}, 錯誤位置: {error['error_positions']}")
# 統計重複的錯誤位置及其次數
error_positions_counter = Counter([pos for error in error_details for pos in error["error_positions"]])
print("錯誤位置及其次數:")
for position, count in error_positions_counter.items():
print(f"位置 {position}: {count} 次")
all_count += count
print(f'總花費時間:{all_time}秒,單測項平均時間:{round((all_time/i),3)}秒')
print(f'誤判率 :{round(all_count/(i*15),2)*100}%')
print(f'總字元數:{i*15},誤判總字元數:{all_count}')

if __name__ == "__main__":
rename_images()

Easy OCR程式範例

import os
from PIL import Image
import re
import time
import numpy as np
from collections import Counter
import easyocr
import cv2

def find_errors(ocr_results, file_names):
error_details = []

for ocr, file_name in zip(ocr_results, file_names):
if ocr != file_name:
error_positions = [(i, a, b) for i, (a, b) in enumerate(zip(ocr, file_name)) if a != b]
error_details.append({"ocr": ocr, "file_name": file_name, "error_positions": error_positions})

return error_details

def rename_images():
res_str = 0
ocr_results = [] # 你的OCR結果清單
file_names = [] # 你的檔案名稱清單
all_time = 0
all_count = 0
count = 0
'''
Change File Name -> OCR.Png
'''
folder_path = "圖片路徑"
valid_extensions = [".jpg", ".png", ".jpeg"]
reader = easyocr.Reader(['ch_sim','en'], gpu=False) # this needs to run only once to load the model into memory

image_files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and any(f.lower().endswith(ext) for ext in valid_extensions)]
files = [f for f in os.listdir(folder_path) if os.path.isfile(os.path.join(folder_path, f)) and f.lower().endswith(".png")]

for i, (image_file, file_1) in enumerate(zip(image_files, files)):

_, extension = os.path.splitext(image_file)
original_path = os.path.join(folder_path, image_file)
file = file_1.split('_')[0]
# 使用 pytesseract 讀取文字
try:
start_time = time.time()
img = cv2.imread(original_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
labels = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
ocr_text = reader.readtext(labels, detail = 0)
print(ocr_text)
except Exception as e:
print(f"Error reading text from {image_file}: {e}")
continue
# 使用 join 方法將列表轉換為字符串
result_string = ''.join(ocr_text)
# print(f'辨識到的OCR:{ocr_text}')
ocr_results.append(result_string) # 你的OCR結果清單
file_names.append(file) # 你的檔案名稱清單
if ocr_text == file:
res_str += 1

end_time = time.time()
elapsed_time = end_time - start_time
all_time += elapsed_time
print(f"處理 第{i} 張圖片共花費 {elapsed_time:.2f} 秒")

print(f'準確率:{(res_str/(i + 1) )*100}%,總共測試了{i + 1}張,誤判{((i + 1)-res_str)}張')

error_details = find_errors(ocr_results, file_names)
print("錯誤字母詳細資訊:")
for error in error_details:
print(f"OCR: {error['ocr']}, 檔案名稱: {error['file_name']}, 錯誤位置: {error['error_positions']}")
# 統計重複的錯誤位置及其次數
error_positions_counter = Counter([pos for error in error_details for pos in error["error_positions"]])
print("錯誤位置及其次數:")
for position, count in error_positions_counter.items():
print(f"位置 {position}: {count} 次")
all_count += count
print(f'總花費時間:{all_time}秒,單測項平均時間:{round((all_time/i),3)}秒')
print(f'誤判率 :{round(all_count/(i*15),2)*100}%')
print(f'總字元數:{i*15},誤判總字元數:{all_count}')

if __name__ == "__main__":
rename_images()



分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.