+14

Nhận diện và trích xuất thông tin biển số xe Việt Nam - Identify and Extract Vietnamese License Plate information

1. Lời nói đầu

Cùng với sự phát triển về khoa học và tốc độ xử lý của máy tính ngày càng cao, việc áp dụng trí tuệ nhân tạo vào các lĩnh vực trong đời sống đã trở thành xu hướng phát triển không thể bỏ qua. Bằng các sử dụng các kỹ thuật xử lý ảnh và trí tuệ nhân tạo, bài toán nhận diện và trích xuất biển số xe đã trở nên phổ biến và tiện lợi hơn bao giờ hết, đóng vai trò quan trọng trong việc quản lý giao thông và đảm bảo an toàn cho người tham gia giao thông. Trong bài viết này, tôi sẽ giới thiệu về bài toán nhận diện và trích xuất thông tin biển số xe và thực hành xây dựng nó. Code và data để thực hiện dự án các bạn có thể tham khảo thêm tại đây.

2. Chuẩn bị dữ liệu

GreenParking là bộ dữ liệu được mình sử dụng để training với YOLOv7 (You Only Live Once), dữ liệu đã được mình tải trong github. Để train dữ liệu này với Yolo thì ta cần tực hiện gán nhãn mỗi ảnh tọa độ của vùng chứa biển số xe (x, y, w, h). Ở đây mình sử dụng công cụ LabelImage được hỗ trợ bởi python để thực hiện việc gán nhãn. Để cài đặt và sử dụng bạn có thể tham khảo tại đây. Một số thao tác quan trọng mình liệt kê như sau:

Phím tắt Chức năng
Ctrl + s Lưu
Ctrl + u Tải toàn bộ ảnh từ một folder
w Mở chức năng vẽ bounding box
d Ảnh tiếp theo
a Ảnh trước đó
del xóa bounding box đang vẽ

3. Quy trình thực hiện bài toán

Quá trình mình thực hiện gồm 4 bước:

  • Xác định vùng ảnh chứa biển số xe bằng Yolov7 và lưu ảnh đã vẽ countour vào folder results_detect.
  • Cắt đối tượng đó và lưu vào folder results_crop.
  • Trích xuất thông tin bằng kỹ thuật OCR
  • In kết quả

3.1. Xác định vùng ảnh chứa biển số xe.

3.1.1. Sử dụng YOLO - YOLOV7

Cách train Yolo các bạn có thể tham khảo tại file code train_yolov7.ipynb. Vì đối tượng đầu ra của bài toán chỉ là biển số xe, vì vậy số lượng đối tượng là 1, tương đương với index class là 0 nhưng labelimg đã được huấn luyện sẵn một số đối tượng nên đầu ra sẽ có index class > 0 thì chúng ta không thể thực hiện huấn luyện được vì vậy cần phải chuyển index class về bằng 0. Đây là đoạn code được mình sử dụng để tự động chuyển đổi index class:

# import pandas as pd
# import glob 

for label in glob.glob('*.txt'): 
  location = list(pd.read_csv(label, sep = " ", on_bad_lines='skip').columns)
  location[0] = '0'
  with open(label, 'w') as f: 
    for idx, coor in enumerate(location):
      if idx != 4:
        f.write(coor)
        f.write(" ") 
      else: 
        f.write(coor)

Sau khi thực hiện xử lý dữ liệu huấn luyện, tiếp theo các bạn cần đi đến bước nạp dữ liệu và điều chỉnh tham số:

#!rm data/mydataset.yaml # if exist
!echo 'train: ../train_data/train' >> data/mydataset.yaml
!echo 'val: ../train_data/train' >> data/mydataset.yaml
!echo 'nc: 1' >> data/mydataset.yaml
!echo "names: ['license plate']" >> data/mydataset.yaml

Ở đây mình chọn số lượng class (nc) là 1 với tên của class là "license plate" với tập dữ liệu training và validation đều là giống nhau. Tiếp theo sẽ đi đến bước huấn luyện mô hình, để chọn model nào cho Yolo V7 thì tùy thuộc vào nhu cầu bài toán của bạn và chi phí xử lý cũng như khả năng tính toán của máy tính. Mình thực hiện trên colab và đánh giá 2 model được sử dụng như sau:

  • Với model v7 để đạt được các chỉ số Precision, Recall và mAP@0.5 lần lượt là 1, 1 và 0.995 cần 50-60 epochs để hội tụ.
  • Tương tự với model v7x thì chỉ cần 10 epochs, tuy nhiên chi phí và thời gian tính toán cho 1 epoch của v7x lớn hơn rất nhiều so với v7. Lưu ý: Nếu các bạn không muốn thực hiện training lại có thể tải file weight mình đã train sẵn ở đường link gắn bên trong file best_pt.txt

3.1.2. Sử dụng kỹ thuật xử lý ảnh bằng OpenCV

Với phương pháp xử lý ảnh mình sẽ giải quyết bài toán lần lượt theo từng bước sau:

  1. Đọc ảnh
  2. Chuyển thành ảnh xám
  3. Làm mượt ảnh bằng bộ lọc bilateral
  4. Phát hiện cạnh bằng canny
  5. Tìm countours
  6. Sau khi đã có được các countours ==> Mình tiến hành giảm số contour mục tiêu lại bằng cách lấy 5 contour có diện tích lớn nhất. Cuối cùng sẽ chọn 1 countour có số cạnh là 4 (thõa mãn với object là biển số xe)
  7. Để cải thiện cho quá trình trích xuất thông tin. Mình tiến hành xoay ảnh lại theo hướng nhìn đường chim bay. (xác định góc xoay và hướng xoay). image.png Quy ước:
  • hình chữ nhật màu đen là box mục tiêu
  • hình chữ nhật màu đỏ là box thực tế
  • trục ngang là x, trục dọc là y
  • a, b, c, d là tọa độ (x,y) của từng điểm

Lúc này để có thể xoay từ box đỏ sang box đen ta cần xác định được góc z (màu vàng). Hãy chú ý vào tam giác màu xanh lá. Ở đây để tính được góc z ta có thể sử dụng hàm tan để tính toán.

Theo toán hình học thì. tan = cạnh đối / cạnh kề = A => góc cần xoay = arctan(A). Tiếp theo xác định hướng xoay và xoay theo hướng đó với góc tính được.

Đây là kết quả của mình thu được khi thực hiện xoay bằng openCV. Code các bạn có thể tham khảo tại đây

image.png

3.2 Trích xuất thông tin bằng kỹ thuật OCR.

Đầu tiên bạn cần biết OCR là gì: OCR là viết tắt của Optical Character Recognition, là một công nghệ (lưu ý rằng OCR không phải một mô hình hay thuật toán) dùng để nhận dạng và chuyển đổi hình ảnh hoặc tài liệu văn bản thành dữ liệu có thể sử dụng được bằng máy tính. Trước đây, khi cần đưa tài liệu giấy vào hệ thống máy tính để xử lý, người dùng phải gõ lại các thông tin từ tài liệu giấy thành văn bản trên máy tính. Tuy nhiên, với sự phát triển của OCR, quá trình này trở nên đơn giản hơn rất nhiều. OCR có thể quét hình ảnh hoặc tài liệu văn bản, phân tích các ký tự trong hình ảnh đó, sau đó chuyển đổi chúng thành văn bản có thể sửa đổi được. OCR được sử dụng rộng rãi trong nhiều lĩnh vực như quản lý tài liệu, xử lý ảnh y khoa, xử lý ngôn ngữ tự nhiên và nhiều lĩnh vực khác. OCR được áp dụng trong các ứng dụng như quét tài liệu, chuyển đổi tài liệu giấy thành định dạng điện tử, tạo bản sao điện tử của tài liệu, xử lý dữ liệu từ các tài liệu giấy, và nhiều ứng dụng khác.

Bạn có thể cài đặt OCR bằng dòng lệnh:

pip install easyocr

4. Kết quả

image.png

Project nhận diện và trích xuất thông tin biển số xe của mình đã thực hiện được. Tuy nhiên đây chỉ là một module được mình triển khai một cách sơ khai nên còn tồn tại một số nhược điểm: tốc độ xử lý còn khá kém, hoạt động kém với ảnh quá mờ, ....

Hy vọng bài viết của mình sẽ giúp ích cho các bạn. Các bạn có câu hỏi hay thắc mắc gì thì hãy comment cho mình nhé. Để tạo thêm động lực cho mình các bạn có thể giúp mình upvote bài viết nhé !! 😚😚😚


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí