Nhận diện biển số xe hơi – Phần 1/3 tìm biển số

car_plate1

Bài này sẽ hướng dẫn các bạn đọc biển số xe hơi loại dài ở Việt Nam. Biển số này có đặc trưng là chiều dài gấp 4 lần chiều rộng. Trong khi loại biển vuông thì chiều dài gấp 1.3 lần chiều rộng.

Lấy ý tưởng chính từ cuốn ebook Mastering OpenCV. Trong bài viết gốc là loại biển số của Tây Ban Nha, cũng là biển số theo chuẩn chung của Euro. Do đó tui có sửa đổi một số chỗ cho phù hợp với biển số xe hơi Việt Nam.

Ảnh tui sử dụng là 1 chiếc xe có biển số ở Hà Nội, có kích thước 600×450 pixels

đọc biển số xe hơi

Bài này cũng chỉ giới hạn trong các loại biển số xe nằm ngang hoặc hơi nghiêng và chất lượng ảnh tương đối tốt. Các biển quá nghiêng, quá xéo hoặc bị mờ sẽ được viết trong một bài nâng cao khác. Khuôn khổ bài này chủ yếu để giải thích, hướng dẫn thuật toán và so sánh với các thuật toán khác.

Lý thuyết

Để đọc biển số dài cần qua 3 bước chính:
1. Tìm vị trí của biển số, kết quả bước này là biển số xe đã crop
2. Tách ký tự từ biển số xe
3. Nhận diện ký tự và hiển thị

Trong bài này sẽ giới thiệu cách tìm vị trí của biển số, sử dụng ngôn ngữ C++ và thư viện opencv 3.2.0 để thực hiện.

Bước 1: Tìm edge (cạnh)

Sobel filter là thuật toán dùng để tìm edge trong ảnh, vì biển số xe có đặc trưng là các ký tự màu đen trên hình chữ nhật nền trắng. Màu đen – trắng tương phản cao nên chúng ta dùng thuật toán Sobel filter để tìm.

sobel filter

Sau đó nhị phân hóa sẽ được các vùng có độ tương phản cao nhất

sobel and threshold

Phương thức này tìm biển số dựa trên độ tương phản cao của ký tự biển số. Như vậy với ảnh biển số bị nhòe thuật toán này sẽ không làm việc tốt. (À mà nhòe quá thì mua camera tốt 1 chút cho khỏe)

Bước 2: tìm các cạnh có khả năng là biển số

Tiếp theo là sử dụng thuật toán Morphology Closing để nối liền khoảng cách các ký tự.

Screenshot 2017-11-06 22.19.58

Tuy nhiên sẽ có nhiều blob nhỏ cũng được thuật toán Closing nối liền lại thành blob lớn. Lúc này để tìm được đâu là blob lớn nhất chúng ta dựa vào đặc trưng về hình dáng, bao gồm:
– Kích cỡ phải nằm trong khoảng cho phép (do user định nghĩa). Hiện tại ảnh có kích thước 600×450 pixels. Do đó tui định nghĩa chiều rộng không được vượt quá 500 pixels. Còn chiều rộng không được nhỏ hơn 100 pixels, do nhỏ hơn 100 pixels thì rất khó để nhận diện ký tự.
– Chiều rộng gấp chiều cao hơn 3 lần

Áp dụng những đặc trưng trên để tìm thì tìm được contour đáp ứng đủ yêu cầu
contour filtered

Một số trường hợp khác

car_plate2

car_plate3

car_plate4

Hình ảnh không phát hiện được

Ảnh có kích thước nhỏ và hình ảnh bị nhòe
0146_1422_b

Vài lưu ý

Trong source gốc có kiểm tra thêm 1 lần nữa để chắc chắn rằng đó là biển số bằng cách sử dụng SVM. Tuy nhiên sau khi test thử thì độ chính xác quá thấp nên không dùng SVM nữa.

Khung chữ nhật bao lấy biển số là cv::RotatedRect (không phải cv::Rect) vì biển số có thể nghiêng 1 chút chứ không phải lúc nào cũng nằm ngang.

Kết luận

Thuật toán này áp dụng tốt với trường hợp biển số rõ nét, kích thước lớn. Các trường hợp khác có thể áp dụng giải thuật khác, hoặc có cách đơn giản hơn là mua camera chất lượng tốt hơn, hoặc thay đổi góc, vị trí lắp đặt camera thay vì phải nghiên cứu giải thuật.

Đọc tiếp: Nhận diện biển số xe hơi – Phần 2/3 tìm ký tự

Leave a Reply