Việc trích xuất văn bản từ hình ảnh và tài liệu theo cách thủ công có thể rất tẻ nhạt và tốn thời gian. May mắn thay, OCR (Optical Character Recognition) có thể tự động hóa quy trình này, cho phép bạn chuyển đổi những hình ảnh đó thành các tệp văn bản có thể chỉnh sửa và tìm kiếm.
Các kỹ thuật bạn sắp học có thể áp dụng trong nhiều ứng dụng:
Số hóa tài liệu giấy: Chuyển đổi tài liệu đã quét, PDF hoặc ảnh chụp văn bản thành tệp có thể chỉnh sửa và tìm kiếm.
Tự động nhập liệu: Trích xuất thông tin từ biểu mẫu, hóa đơn, biên lai và các tài liệu khác để tự động điền vào cơ sở dữ liệu hoặc bảng tính.
Cải thiện khả năng tiếp cận: Tạo phiên bản văn bản số của sách, thực đơn hoặc biển báo cho người khiếm thị. Sau đó có thể dùng công cụ chuyển văn bản thành giọng nói để đọc to.
Xe tự lái: Nhận diện biển báo giao thông và biển số để điều hướng an toàn.
Hướng dẫn này tập trung vào động cơ OCR Tesseract và API Python của nó - PyTesseract. Trước khi bắt đầu viết mã, hãy điểm qua nhanh một số thư viện phổ biến dành cho OCR.
Các thư viện OCR mã nguồn mở hàng đầu trong Python
Vì OCR là một bài toán phổ biến và liên tục được quan tâm, nhiều thư viện mã nguồn mở đã cố gắng giải quyết nó. Trong phần này, chúng ta sẽ đề cập đến những thư viện đạt được nhiều phổ biến nhờ hiệu năng và độ chính xác cao.
Tesseract
Tesseract OCR là một động cơ nhận dạng ký tự quang học mã nguồn mở phổ biến nhất trong giới lập trình viên. Giống các công cụ khác trong danh sách này, Tesseract có thể lấy hình ảnh chứa văn bản và chuyển đổi chúng thành văn bản có thể chỉnh sửa.
Ưu điểm
Thư viện trưởng thành, được dùng rộng rãi với cộng đồng lớn
Hỗ trợ hơn 100 ngôn ngữ
Miễn phí và mã nguồn mở
Nhược điểm
Độ chính xác có thể thấp hơn so với một số giải pháp dựa trên học sâu
Tùy chọn cấu hình hạn chế
Easy OCR
EasyOCR là một thư viện Python được thiết kế để nhận dạng ký tự quang học (OCR) một cách dễ dàng. Đúng như tên gọi, nó cung cấp cách tiếp cận thân thiện để trích xuất văn bản từ hình ảnh.
Ưu điểm
Thân thiện với người dùng và dễ thiết lập
Độ chính xác cao với các mô hình học sâu
Hỗ trợ nhiều ngôn ngữ ngay từ đầu
Nhược điểm
Phụ thuộc vào các mô hình huấn luyện sẵn, có thể có kích thước lớn
Có thể chậm hơn Tesseract với các tác vụ đơn giản
Keras OCR
Keras-OCR là thư viện Python xây dựng trên Keras, một framework học sâu phổ biến. Nó cung cấp các mô hình OCR sẵn dùng và một quy trình huấn luyện đầu-cuối để xây dựng mô hình OCR mới.
Ưu điểm
Cách tiếp cận dựa trên học sâu, cho độ chính xác cao với nhiều loại văn bản
Tùy biến lựa chọn và huấn luyện mô hình
Có thể chính xác hơn trên bố cục phức tạp hoặc chữ viết tay
Nhược điểm
Cần GPU để đạt hiệu năng tối ưu
Độ khó học cao hơn do bản chất học sâu
Huấn luyện mô hình tùy chỉnh tốn thời gian
Dưới đây là bảng tóm tắt khác biệt, ưu và nhược điểm của chúng:
Tên gói
Ưu điểm
Nhược điểm
Tesseract (pytesseract)
Trưởng thành, dùng rộng rãi, hỗ trợ phong phú
Chậm hơn, độ chính xác thấp hơn trên bố cục phức tạp
EasyOCR
Dễ dùng, nhiều mô hình
Độ chính xác thấp hơn, tùy biến hạn chế
Keras-OCR
Độ chính xác cao hơn, có thể tùy biến
Cần GPU, đường cong học tập dốc
Trong hướng dẫn này, chúng ta sẽ tập trung vào PyTesseract, API Python của Tesseract. Chúng ta sẽ học cách trích xuất văn bản từ hình ảnh đơn giản, cách vẽ hộp giới hạn quanh văn bản và thực hiện một nghiên cứu tình huống với tài liệu đã quét.
Hướng dẫn từng bước về OCR với PyTesseract & OpenCV
Cài đặt
PyTesseract hoạt động dựa trên động cơ Tesseract chính thức, là một phần mềm CLI riêng. Trước khi cài đặt pytesseract, bạn phải cài sẵn động cơ này. Dưới đây là hướng dẫn cài đặt cho các nền tảng khác nhau.
Dễ như vậy thôi! Hãy chuyển những gì vừa làm thành một hàm:
defimage_to_text(input_path):"""
A function to read text from images.
"""
img = cv2.imread(input_path)
text = pytesseract.image_to_string(img)return text.strip()Được hỗ trợ bởi
Hãy dùng hàm này trên một hình ảnh khó hơn:
Hình ảnh này thách thức hơn vì có nhiều dấu câu và văn bản ở các phông chữ khác nhau.
# Define image path
medium_text_path ="images/medium_text.png"# Extract text
extracted_text = image_to_text(medium_text_path)print(extracted_text)Được hỗ trợ bởi
Home > Tutorials » Data Engineering
Snowflake Tutorial For Beginners:
From Architecture to Running
Databases
Learn the fundamentals of cloud data warehouse management using
Snowflake. Snowflake is a cloud-based platform that offers significant
benefits for companies wanting to extract as much insight from their data as
quickly and efficiently as possible.
Jan 2024 - 12 min read
Được hỗ trợ bởi
Hàm của chúng ta hoạt động gần như hoàn hảo. Nó nhầm một trong các dấu chấm và ký hiệu “>”, nhưng kết quả nhìn chung vẫn chấp nhận được.
Vẽ hộp giới hạn quanh văn bản
Một thao tác phổ biến trong OCR là vẽ các hộp giới hạn quanh văn bản. PyTesseract hỗ trợ thao tác này.
Trước tiên, truyền một ảnh đã tải vào hàm image_to_data:
from pytesseract import Output
# Extract recognized data from easy text
data = pytesseract.image_to_data(easy_img, output_type=Output.DICT)Được hỗ trợ bởi
Phần Output.DICT đảm bảo chi tiết ảnh được trả về dưới dạng dictionary. Hãy xem bên trong:
Điều này có nghĩa pytesseract đã vẽ 11 hộp. conf là mức độ tự tin. Nếu bằng -1, thì hộp tương ứng được vẽ quanh khối văn bản thay vì từng từ riêng lẻ.
Ví dụ, nếu bạn nhìn bốn giá trị width và height đầu tiên, chúng lớn hơn phần còn lại vì những hộp đó được vẽ quanh toàn bộ văn bản ở giữa, sau đó là từng dòng văn bản và toàn bộ ảnh.
Ngoài ra:
left là khoảng cách từ góc trên bên trái của hộp giới hạn đến viền trái của ảnh.
top là khoảng cách từ góc trên bên trái của hộp giới hạn đến viền trên của ảnh.
width và height là chiều rộng và chiều cao của hộp giới hạn.
Dựa trên các thông tin này, hãy vẽ các hộp đè lên ảnh trong OpenCV.
Đầu tiên, chúng ta lại trích xuất dữ liệu và độ dài của nó:
from pytesseract import Output
# Extract recognized data
data = pytesseract.image_to_data(easy_img, output_type=Output.DICT)
n_boxes =len(data["text"])Được hỗ trợ bởi
Sau đó, tạo một vòng lặp theo số hộp tìm được:
for i inrange(n_boxes):if data["conf"][i]==-1:continueĐược hỗ trợ bởi
Bên trong vòng lặp, tạo điều kiện bỏ qua lượt lặp hiện tại nếu conf bằng -1. Bỏ qua các hộp lớn hơn sẽ giúp ảnh gọn gàng.
Tiếp đó, xác định tọa độ của hộp hiện tại, cụ thể là vị trí của góc trên bên trái và góc dưới bên phải:
for i inrange(n_boxes):if data["conf"][i]==-1:continue# Coordinates
x, y = data["left"][i], data["top"][i]
w, h = data["width"][i], data["height"][i]# Corners
top_left =(x, y)
bottom_right =(x + w, y + h)Được hỗ trợ bởi
Sau khi xác định một số tham số hộp, như màu hộp và độ dày tính bằng pixel, chúng ta truyền tất cả thông tin vào hàm cv2.rectangle:
for i inrange(n_boxes):if data["conf"][i]==-1:continue# Coordinates
x, y = data["left"][i], data["top"][i]
w, h = data["width"][i], data["height"][i]# Corners
top_left =(x, y)
bottom_right =(x + w, y + h)# Box params
green =(0,255,0)
thickness =3# pixels
cv2.rectangle(
img=easy_img, pt1=top_left, pt2=bottom_right, color=green, thickness=thickness
)Được hỗ trợ bởi
Hàm sẽ vẽ các hộp đè lên ảnh gốc. Hãy lưu ảnh và xem thử:
# Save the image
output_image_path ="images/text_with_boxes.jpg"
cv2.imwrite(output_image_path, easy_img)Được hỗ trợ bởi
defdraw_bounding_boxes(input_img_path, output_path):
img = cv2.imread(input_img_path)# Extract data
data = pytesseract.image_to_data(img, output_type=Output.DICT)
n_boxes =len(data["text"])for i inrange(n_boxes):if data["conf"][i]==-1:continue# Coordinates
x, y = data["left"][i], data["top"][i]
w, h = data["width"][i], data["height"][i]# Corners
top_left =(x, y)
bottom_right =(x + w, y + h)# Box params
green =(0,255,0)
thickness =1# The function-version uses thinner lines
cv2.rectangle(img, top_left, bottom_right, green, thickness)# Save the image with boxes
cv2.imwrite(output_path, img)Được hỗ trợ bởi
Và dùng hàm cho văn bản mức trung bình-khó:
output_path ="images/medium_text_with_boxes.png"
draw_bounding_boxes(medium_text_path, output_path)Được hỗ trợ bởi
Ngay cả với ảnh khó hơn, kết quả vẫn hoàn hảo!
Nghiên cứu tình huống: OCR trên tệp PDF bằng Python
Hãy thực hiện một nghiên cứu tình huống trên một tệp PDF quét mẫu. Trên thực tế, nhiều khả năng bạn sẽ làm việc với PDF đã quét thay vì hình ảnh, như thế này:
import pathlib
from pathlib import Path
from pdf2image import convert_from_path
Được hỗ trợ bởi
Hàm convert_from_path chuyển một PDF đã cho thành một loạt ảnh. Dưới đây là một hàm lưu từng trang của tệp PDF thành ảnh vào thư mục chỉ định:
defpdf_to_image(pdf_path, output_folder:str="."):"""
A function to convert PDF files to images
"""# Create the output folder if it doesn't existifnot Path(output_folder).exists():
Path(output_folder).mkdir()
pages = convert_from_path(pdf_path, output_folder=output_folder, fmt="png")return pages
Được hỗ trợ bởi
Hãy chạy nó trên tài liệu của chúng ta:
pdf_path ="scanned_document.pdf"
pdf_to_image(pdf_path, output_folder="documents")Được hỗ trợ bởi
[<PIL.PngImagePlugin.PngImageFileimagemode=RGBsize=1662x2341>]
Được hỗ trợ bởi
Đầu ra là một danh sách chứa một đối tượng ảnh PngImageFile. Hãy xem thư mục documents:
Ảnh đã có ở đó, vậy hãy truyền nó vào hàm image_to_text mà chúng ta tạo lúc đầu và in vài trăm ký tự đầu tiên của văn bản trích xuất:
scanned_img_path ="documents/2d8f6922-99c4-4ef4-a475-ef81effe65a3-1.png"print(image_to_text(scanned_img_path)[:377])Được hỗ trợ bởi
PEU Business report
New customer's development
and increasing the sale of product
My country economy at this season keeps escaping from Odoba of business though holds a crude oil
high so on unstable element that continues still, and recovering gradually and well.
In the IT industry, there is an influence such as competing intensification in narrowing investment field.
Được hỗ trợ bởi
Nếu so sánh văn bản với tệp, mọi thứ đều hoạt động tốt — định dạng và khoảng cách được giữ nguyên, và văn bản chính xác. Vậy làm sao để chia sẻ văn bản đã trích xuất?
Định dạng tốt nhất để chia sẻ văn bản PDF đã trích xuất là một tệp PDF khác! PyTesseract có hàm image_to_pdf_or_hocr nhận bất kỳ ảnh có văn bản nào và chuyển nó thành tệp PDF thô có thể tìm kiếm văn bản. Hãy dùng nó trên ảnh đã quét của chúng ta:
raw_pdf = pytesseract.image_to_pdf_or_hocr(scanned_img_path)withopen("searchable_pdf.pdf","w+b")as f:
f.write(bytearray(raw_pdf))Được hỗ trợ bởi
Và đây là giao diện của searchable_pdf:
Như bạn thấy, tôi có thể tô sáng và sao chép văn bản từ tệp. Ngoài ra, mọi thành phần của PDF gốc đều được giữ nguyên.
Các kỹ thuật tiền xử lý ảnh cho OCR trong OpenCV
Không có cách tiếp cận “một cho tất cả” cho OCR. Các kỹ thuật hôm nay chúng ta đề cập có thể không hiệu quả với các loại ảnh khác. Tôi khuyến nghị bạn thử nghiệm các kỹ thuật tiền xử lý ảnh và cấu hình Tesseract khác nhau để tìm thiết lập tối ưu cho từng ảnh cụ thể.
Yếu tố quan trọng nhất trong OCR là chất lượng hình ảnh. Ảnh được quét đúng chuẩn, thẳng đứng hoàn toàn và có độ tương phản cao (đen trắng) thường hoạt động tốt nhất với mọi phần mềm OCR. Hãy nhớ, chỉ vì bạn đọc được văn bản không có nghĩa là máy tính của bạn cũng vậy.
Nếu ảnh của bạn không đạt các tiêu chuẩn chất lượng cao của Tesseract và đầu ra là “mớ hỗn độn”, thì có một số bước tiền xử lý bạn có thể thực hiện.
1. Chuyển sang thang xám (grayscale)
Đầu tiên, hãy chuyển đổi ảnh màu sang thang xám. Điều này có thể cải thiện độ chính xác bằng cách loại bỏ các biến thiên màu sắc có thể gây nhiễu quá trình nhận dạng. Trong OpenCV, sẽ như sau:
defgrayscale(image):"""Converts an image to grayscale.
Args:
image: The input image in BGR format.
Returns:
The grayscale image.
"""return cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)Được hỗ trợ bởi
2. Giảm nhiễu
Không phải tất cả hình ảnh, đặc biệt là tài liệu đã quét, đều có nền sạch và đồng nhất. Ngoài ra, một số ảnh có thể từ tài liệu cũ, nơi trang bị xuống cấp theo thời gian. Đây là một ví dụ:
Áp dụng các kỹ thuật như bộ lọc khử nhiễu (ví dụ, làm mờ trung vị) để giảm nhiễu trong ảnh có thể dẫn đến hiểu sai trong quá trình OCR. Trong OpenCV, bạn có thể dùng hàm medianBlur:
defdenoise(image):"""Reduces noise in the image using a median blur filter.
Args:
image: The input grayscale image.
Returns:
The denoised image.
"""return cv2.medianBlur(image,5)# Adjust kernel size as neededĐược hỗ trợ bởi
3. Làm sắc nét
Trong một số trường hợp, làm sắc nét ảnh có thể tăng cường biên và cải thiện nhận dạng ký tự, đặc biệt với ảnh mờ hoặc độ phân giải thấp. Có thể làm sắc nét bằng cách áp dụng bộ lọc Laplacian trong OpenCV:
defsharpen(image):"""Sharpens the image using a Laplacian filter.
Args:
image: The input grayscale image.
Returns:
The sharpened image (be cautious with sharpening).
"""
kernel = np.array([[0,-1,0],[-1,5,-1],[0,-1,0]])return cv2.filter2D(image,-1, kernel)Được hỗ trợ bởi
4. Nhị phân hóa (binarization)
Với một số ảnh, nhị phân hóa (chuyển ảnh thành đen trắng) có thể hữu ích. Hãy thử nghiệm các kỹ thuật ngưỡng khác nhau để tìm cách tách tối ưu giữa tiền cảnh (văn bản) và nền.
Tuy nhiên, nhị phân hóa có thể nhạy cảm với biến thiên ánh sáng và không phải lúc nào cũng cần thiết. Đây là ví dụ ảnh sau khi nhị phân hóa:
Để thực hiện nhị phân hóa trong OpenCV, bạn có thể dùng hàm adaptiveThreshold:
defbinarize(image):"""Binarizes the image using adaptive thresholding.
Args:
image: The input grayscale image.
Returns:
The binary image.
"""
thresh = cv2.adaptiveThreshold(
image,255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY,11,2)return thresh
Được hỗ trợ bởi
5. Các kỹ thuật khác
Có nhiều kỹ thuật tiền xử lý khác, chẳng hạn:
Giãn (Dilation): làm đậm các phông chữ nhỏ và mảnh để cải thiện nhận dạng
Xói mòn (Erosion): làm mòn văn bản đậm để cải thiện độ chính xác. Phổ biến trong tài liệu cổ với phông dày.
Phát hiện biên Canny
Hiệu chỉnh nghiêng: chỉnh độ nghiêng của các dòng chữ. Phổ biến trong tài liệu quét sai cách
Trong bài viết này, bạn đã có những bước đầu tiên tìm hiểu về bài toán năng động mang tên OCR. Chúng ta bắt đầu với cách trích xuất văn bản từ ảnh đơn giản, rồi chuyển sang ảnh khó hơn với định dạng phức tạp.
Chúng ta cũng đã học một quy trình đầu-cuối để trích xuất văn bản từ PDF đã quét và cách lưu văn bản trích xuất lại thành PDF để có thể tìm kiếm. Bài viết khép lại với một số mẹo cải thiện chất lượng ảnh bằng OpenCV trước khi đưa vào Tesseract.
Nếu bạn muốn học thêm về giải quyết các bài toán liên quan đến hình ảnh, dưới đây là một số tài nguyên thị giác máy tính để bạn tham khảo:
Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn.
Vì sao nên học Nhận dạng Ký tự Quang học (OCR)?
Việc trích xuất văn bản từ hình ảnh và tài liệu theo cách thủ công có thể rất tẻ nhạt và tốn thời gian. May mắn thay, OCR (Optical Character Recognition) có thể tự động hóa quy trình này, cho phép bạn chuyển đổi những hình ảnh đó thành các tệp văn bản có thể chỉnh sửa và tìm kiếm.
Các kỹ thuật bạn sắp học có thể áp dụng trong nhiều ứng dụng:
Hướng dẫn này tập trung vào động cơ OCR Tesseract và API Python của nó - PyTesseract. Trước khi bắt đầu viết mã, hãy điểm qua nhanh một số thư viện phổ biến dành cho OCR.
Các thư viện OCR mã nguồn mở hàng đầu trong Python
Vì OCR là một bài toán phổ biến và liên tục được quan tâm, nhiều thư viện mã nguồn mở đã cố gắng giải quyết nó. Trong phần này, chúng ta sẽ đề cập đến những thư viện đạt được nhiều phổ biến nhờ hiệu năng và độ chính xác cao.
Tesseract
Tesseract OCR là một động cơ nhận dạng ký tự quang học mã nguồn mở phổ biến nhất trong giới lập trình viên. Giống các công cụ khác trong danh sách này, Tesseract có thể lấy hình ảnh chứa văn bản và chuyển đổi chúng thành văn bản có thể chỉnh sửa.
Ưu điểm
Nhược điểm
Easy OCR
EasyOCR là một thư viện Python được thiết kế để nhận dạng ký tự quang học (OCR) một cách dễ dàng. Đúng như tên gọi, nó cung cấp cách tiếp cận thân thiện để trích xuất văn bản từ hình ảnh.
Ưu điểm
Nhược điểm
Keras OCR
Keras-OCR là thư viện Python xây dựng trên Keras, một framework học sâu phổ biến. Nó cung cấp các mô hình OCR sẵn dùng và một quy trình huấn luyện đầu-cuối để xây dựng mô hình OCR mới.
Ưu điểm
Nhược điểm
Dưới đây là bảng tóm tắt khác biệt, ưu và nhược điểm của chúng:
Tên gói
Ưu điểm
Nhược điểm
Tesseract (pytesseract)
Trưởng thành, dùng rộng rãi, hỗ trợ phong phú
Chậm hơn, độ chính xác thấp hơn trên bố cục phức tạp
EasyOCR
Dễ dùng, nhiều mô hình
Độ chính xác thấp hơn, tùy biến hạn chế
Keras-OCR
Độ chính xác cao hơn, có thể tùy biến
Cần GPU, đường cong học tập dốc
Trong hướng dẫn này, chúng ta sẽ tập trung vào
PyTesseract, API Python của Tesseract. Chúng ta sẽ học cách trích xuất văn bản từ hình ảnh đơn giản, cách vẽ hộp giới hạn quanh văn bản và thực hiện một nghiên cứu tình huống với tài liệu đã quét.Hướng dẫn từng bước về OCR với PyTesseract & OpenCV
Cài đặt
PyTesseract hoạt động dựa trên động cơ Tesseract chính thức, là một phần mềm CLI riêng. Trước khi cài đặt pytesseract, bạn phải cài sẵn động cơ này. Dưới đây là hướng dẫn cài đặt cho các nền tảng khác nhau.
Với Ubuntu hoặc WSL2 (lựa chọn của tôi):
Với Mac dùng Homebrew:
Với Windows, hãy làm theo hướng dẫn từ trang GitHub này.
Tiếp theo, tạo một môi trường ảo mới. Tôi sẽ dùng Conda:
Sau đó, bạn cần cài
pytesseractđể thực hiện OCR vàopencvđể xử lý ảnh:Nếu bạn theo dõi hướng dẫn này trong Jupyter, hãy chạy các lệnh này trong cùng phiên terminal để môi trường ảo mới được thêm làm kernel:
Giờ chúng ta có thể bắt đầu viết mã.
Sử dụng cơ bản
Bắt đầu bằng cách nhập các thư viện cần thiết:
Nhiệm vụ của chúng ta là đọc văn bản từ hình ảnh sau:
Đầu tiên, chúng ta định nghĩa đường dẫn ảnh và truyền nó vào hàm
cv2.imread:Sau đó, truyền ảnh đã tải vào hàm
image_to_stringcủapytesseractđể trích xuất văn bản:Dễ như vậy thôi! Hãy chuyển những gì vừa làm thành một hàm:
Hãy dùng hàm này trên một hình ảnh khó hơn:
Hình ảnh này thách thức hơn vì có nhiều dấu câu và văn bản ở các phông chữ khác nhau.
Hàm của chúng ta hoạt động gần như hoàn hảo. Nó nhầm một trong các dấu chấm và ký hiệu “>”, nhưng kết quả nhìn chung vẫn chấp nhận được.
Vẽ hộp giới hạn quanh văn bản
Một thao tác phổ biến trong OCR là vẽ các hộp giới hạn quanh văn bản. PyTesseract hỗ trợ thao tác này.
Trước tiên, truyền một ảnh đã tải vào hàm
image_to_data:Phần
Output.DICTđảm bảo chi tiết ảnh được trả về dưới dạng dictionary. Hãy xem bên trong:Dictionary chứa rất nhiều thông tin về ảnh. Trước hết, hãy chú ý đến các khóa
confvàtext. Cả hai đều có độ dài là 11:Điều này có nghĩa
pytesseractđã vẽ 11 hộp.conflà mức độ tự tin. Nếu bằng -1, thì hộp tương ứng được vẽ quanh khối văn bản thay vì từng từ riêng lẻ.Ví dụ, nếu bạn nhìn bốn giá trị
widthvàheightđầu tiên, chúng lớn hơn phần còn lại vì những hộp đó được vẽ quanh toàn bộ văn bản ở giữa, sau đó là từng dòng văn bản và toàn bộ ảnh.Ngoài ra:
leftlà khoảng cách từ góc trên bên trái của hộp giới hạn đến viền trái của ảnh.toplà khoảng cách từ góc trên bên trái của hộp giới hạn đến viền trên của ảnh.widthvàheightlà chiều rộng và chiều cao của hộp giới hạn.Dựa trên các thông tin này, hãy vẽ các hộp đè lên ảnh trong OpenCV.
Đầu tiên, chúng ta lại trích xuất dữ liệu và độ dài của nó:
Sau đó, tạo một vòng lặp theo số hộp tìm được:
Bên trong vòng lặp, tạo điều kiện bỏ qua lượt lặp hiện tại nếu
confbằng -1. Bỏ qua các hộp lớn hơn sẽ giúp ảnh gọn gàng.Tiếp đó, xác định tọa độ của hộp hiện tại, cụ thể là vị trí của góc trên bên trái và góc dưới bên phải:
Sau khi xác định một số tham số hộp, như màu hộp và độ dày tính bằng pixel, chúng ta truyền tất cả thông tin vào hàm
cv2.rectangle:Hàm sẽ vẽ các hộp đè lên ảnh gốc. Hãy lưu ảnh và xem thử:
Kết quả đúng như mong muốn!
Giờ hãy gói gọn mọi thứ vào một hàm nữa:
Và dùng hàm cho văn bản mức trung bình-khó:
Ngay cả với ảnh khó hơn, kết quả vẫn hoàn hảo!
Nghiên cứu tình huống: OCR trên tệp PDF bằng Python
Hãy thực hiện một nghiên cứu tình huống trên một tệp PDF quét mẫu. Trên thực tế, nhiều khả năng bạn sẽ làm việc với PDF đã quét thay vì hình ảnh, như thế này:
Bạn có thể tải PDF từ trang GitHub này của tôi.
Bước tiếp theo là cài đặt thư viện
pdf2image, thư viện này yêu cầu phần mềm xử lý PDF có tên Poppler. Dưới đây là hướng dẫn theo nền tảng:Với Mac:
Với Linux và WSL2:
Với Windows, bạn có thể làm theo hướng dẫn từ tài liệu PDF2Image.
Sau khi cài đặt, hãy nhập các mô-đun liên quan:
Hàm
convert_from_pathchuyển một PDF đã cho thành một loạt ảnh. Dưới đây là một hàm lưu từng trang của tệp PDF thành ảnh vào thư mục chỉ định:Hãy chạy nó trên tài liệu của chúng ta:
Đầu ra là một danh sách chứa một đối tượng ảnh
PngImageFile. Hãy xem thư mụcdocuments:Ảnh đã có ở đó, vậy hãy truyền nó vào hàm
image_to_textmà chúng ta tạo lúc đầu và in vài trăm ký tự đầu tiên của văn bản trích xuất:Nếu so sánh văn bản với tệp, mọi thứ đều hoạt động tốt — định dạng và khoảng cách được giữ nguyên, và văn bản chính xác. Vậy làm sao để chia sẻ văn bản đã trích xuất?
Định dạng tốt nhất để chia sẻ văn bản PDF đã trích xuất là một tệp PDF khác! PyTesseract có hàm
image_to_pdf_or_hocrnhận bất kỳ ảnh có văn bản nào và chuyển nó thành tệp PDF thô có thể tìm kiếm văn bản. Hãy dùng nó trên ảnh đã quét của chúng ta:Và đây là giao diện của
searchable_pdf:Như bạn thấy, tôi có thể tô sáng và sao chép văn bản từ tệp. Ngoài ra, mọi thành phần của PDF gốc đều được giữ nguyên.
Các kỹ thuật tiền xử lý ảnh cho OCR trong OpenCV
Không có cách tiếp cận “một cho tất cả” cho OCR. Các kỹ thuật hôm nay chúng ta đề cập có thể không hiệu quả với các loại ảnh khác. Tôi khuyến nghị bạn thử nghiệm các kỹ thuật tiền xử lý ảnh và cấu hình Tesseract khác nhau để tìm thiết lập tối ưu cho từng ảnh cụ thể.
Yếu tố quan trọng nhất trong OCR là chất lượng hình ảnh. Ảnh được quét đúng chuẩn, thẳng đứng hoàn toàn và có độ tương phản cao (đen trắng) thường hoạt động tốt nhất với mọi phần mềm OCR. Hãy nhớ, chỉ vì bạn đọc được văn bản không có nghĩa là máy tính của bạn cũng vậy.
Nếu ảnh của bạn không đạt các tiêu chuẩn chất lượng cao của Tesseract và đầu ra là “mớ hỗn độn”, thì có một số bước tiền xử lý bạn có thể thực hiện.
1. Chuyển sang thang xám (grayscale)
Đầu tiên, hãy chuyển đổi ảnh màu sang thang xám. Điều này có thể cải thiện độ chính xác bằng cách loại bỏ các biến thiên màu sắc có thể gây nhiễu quá trình nhận dạng. Trong OpenCV, sẽ như sau:
2. Giảm nhiễu
Không phải tất cả hình ảnh, đặc biệt là tài liệu đã quét, đều có nền sạch và đồng nhất. Ngoài ra, một số ảnh có thể từ tài liệu cũ, nơi trang bị xuống cấp theo thời gian. Đây là một ví dụ:
Áp dụng các kỹ thuật như bộ lọc khử nhiễu (ví dụ, làm mờ trung vị) để giảm nhiễu trong ảnh có thể dẫn đến hiểu sai trong quá trình OCR. Trong OpenCV, bạn có thể dùng hàm
medianBlur:3. Làm sắc nét
Trong một số trường hợp, làm sắc nét ảnh có thể tăng cường biên và cải thiện nhận dạng ký tự, đặc biệt với ảnh mờ hoặc độ phân giải thấp. Có thể làm sắc nét bằng cách áp dụng bộ lọc Laplacian trong OpenCV:
4. Nhị phân hóa (binarization)
Với một số ảnh, nhị phân hóa (chuyển ảnh thành đen trắng) có thể hữu ích. Hãy thử nghiệm các kỹ thuật ngưỡng khác nhau để tìm cách tách tối ưu giữa tiền cảnh (văn bản) và nền.
Tuy nhiên, nhị phân hóa có thể nhạy cảm với biến thiên ánh sáng và không phải lúc nào cũng cần thiết. Đây là ví dụ ảnh sau khi nhị phân hóa:
Để thực hiện nhị phân hóa trong OpenCV, bạn có thể dùng hàm
adaptiveThreshold:5. Các kỹ thuật khác
Có nhiều kỹ thuật tiền xử lý khác, chẳng hạn:
Bạn có thể tìm hiểu thêm về cải thiện chất lượng ảnh từ trang tài liệu Tesseract này.
Kết luận
Trong bài viết này, bạn đã có những bước đầu tiên tìm hiểu về bài toán năng động mang tên OCR. Chúng ta bắt đầu với cách trích xuất văn bản từ ảnh đơn giản, rồi chuyển sang ảnh khó hơn với định dạng phức tạp.
Chúng ta cũng đã học một quy trình đầu-cuối để trích xuất văn bản từ PDF đã quét và cách lưu văn bản trích xuất lại thành PDF để có thể tìm kiếm. Bài viết khép lại với một số mẹo cải thiện chất lượng ảnh bằng OpenCV trước khi đưa vào Tesseract.
Nếu bạn muốn học thêm về giải quyết các bài toán liên quan đến hình ảnh, dưới đây là một số tài nguyên thị giác máy tính để bạn tham khảo: