Lý thuyết


Nhận dạng ký tự quang học (Optical Character Recognition – OCR) là kĩ thuật chuyển đổi hình ảnh chữ viết tay hoặc đánh máy thành các văn bản tài liệu. Công nghệ này hiện được phát triển thành nhiều ứng dụng hữu ích như dịch thuật theo thời gian thực, định danh khách hàng điện tử hay xử lý hóa đơn, chứng từ,…. Ngày nay, OCR có khả năng xử lí trên 200 ngôn ngữ và hứa hẹn sẽ tiếp tục mang lại những bước tiến vượt bậc nhờ Trí tuệ nhân tạo.

Có nhiều thư viện OCR, trong đó phổ biến nhất là Tesseract OCR: cung cấp một công cụ OCR – libtesseract và chương trình dòng lệnh – tesseract. So với phiên bản Tesseract 3 thì Tesseract 4 bổ sung một công cụ OCR dựa trên mạng thần kinh nhân tạo (LSTM), tập trung vào nhận dạng dòng và các mẫu ký tự. Tesseract hỗ trợ nhiều định dạng đầu ra như văn bản, hOCR (HTML), PDF, TSV, cũng như thử nghiệm đầu ra ALTO (XML).

Cài đặt thư viện

sudo apt install tesseract-ocr

1. OCR ảnh

Sử dụng ảnh sau để OCR

02.jpg

# import thư viện
from PIL import Image
import pytesseract
import numpy as np
import cv2

# load ảnh cần OCR
img_1 = np.array(Image.open("02.jpg"))
text = pytesseract.image_to_string(img_1)

# show ảnh cần OCR
cv2.imshow("OCR", img_1)

# in kết quả OCR
print("Result OCR: ", text)

# chờ nhấn phím rồi thoát
cv2.waitKey(0)
cv2.destroyAllWindows()

image.png

2. Tiền xử lý ảnh để tăng cường kết quả OCR

Sử dụng code mẫu ở phần 1 nhưng đổi input là ảnh sau để OCR (ảnh đã thêm nhiễu noise cho giống các ảnh thực tế)

03.jpg

Lúc này kết quả OCR là không nhận diện được bất kì kí tự nào

image.png

Tiếp theo, chúng ta sẽ thử sử dụng một chút xử lý hình ảnh để loại bỏ nhiễu trong ảnh, gọi là tiền xử lý. Trong trường hợp này, thử sử dụng các kỹ thuật như chuẩn hóa, ngưỡng và làm mờ ảnh.

# import thư viện
from PIL import Image
import pytesseract
import numpy as np
import cv2

# load ảnh cần OCR
img_1 = np.array(Image.open("03.jpg"))

# đặt tên cửa sổ hiển thị file ảnh 
# cv2.WINDOW_AUTOSIZE -> autosize window theo ảnh
# cv2.WINDOW_NORMAL -> fit ảnh trong window
cv2.namedWindow("OCR", cv2.WINDOW_NORMAL)
cv2.namedWindow("Normalize", cv2.WINDOW_NORMAL)
cv2.namedWindow("Threshold", cv2.WINDOW_NORMAL)
cv2.namedWindow("GaussianBlur", cv2.WINDOW_NORMAL)

# OCR ảnh ko có tiền xử lý
text_1 = pytesseract.image_to_string(img_1)

# show ảnh cần OCR
cv2.imshow("OCR", img_1)

# chuẩn hóa ảnh
norm_img = np.zeros((img_1.shape[0], img_1.shape[1]))
img_2 = cv2.normalize(img_1, norm_img, 0, 255, cv2.NORM_MINMAX)
cv2.imshow("Normalize", img_2)

# lấy ngưỡng
img_3 = cv2.threshold(img_2, 100, 255, cv2.THRESH_BINARY)[1]
cv2.imshow("Threshold", img_3)

# làm mờ
img_4 = cv2.GaussianBlur(img_3, (1, 1), 0)
cv2.imshow("GaussianBlur", img_4)

# OCR ảnh sau tiền xử lý
text_2 = pytesseract.image_to_string(img_4)

# in kết quả OCR
print("Result OCR without image_processing: ", text_1)
print("Result OCR with image_processing: ", text_2)

# chờ nhấn phím rồi thoát
cv2.waitKey(0)
cv2.destroyAllWindows()

Kết quả so sánh giữa trước và sau tiền xử lý ảnh đã cho kết quả OCR tốt hơn nhiều

image.png