ການສ້າງລະບົບວິເຄາະປ້າຍທະບຽນລົດລາວດ້ວຍ Computer Vision
ການສ້າງລະບົບວິເຄາະປ້າຍທະບຽນລົດລາວດ້ວຍ Computer Vision (ALPR)
ດ້ວຍການເຕີບໂຕຂອງຈຳນວນພາຫະນະໃນນະຄອນຫຼວງວຽງຈັນ ແລະ ບັນດາແຂວງໃຫຍ່ໆເຊັ່ນ: ຈຳປາສັກ ແລະ ຫຼວງພະບາງ, ຄວາມຕ້ອງການໃນລະບົບຄຸ້ມຄອງການຈະລາຈອນອັດສະລິຍະ (Smart Traffic Management) ຈຶ່ງກາຍເປັນສິ່ງຈຳເປັນ. ໜຶ່ງໃນເຕັກໂນໂລຊີຫຼັກຂອງລະບົບນີ້ຄື Automatic License Plate Recognition (ALPR) ຫຼື ລະບົບຮັບຮູ້ປ້າຍທະບຽນລົດອັດຕະໂນມັດ.
ໃນຖານະນັກພັດທະນາ ຫຼື ນັກວິໄຈ AI, ທ່ານຄົງຈະຮູ້ດີວ່າການນຳເອົາ Pre-trained Models ຈາກຕ່າງປະເທດມາປັບໃຊ້ກັບປ້າຍທະບຽນລົດລາວໂດຍກົງນັ້ນບໍ່ສາມາດເຮັດວຽກໄດ້ດີ. ສາເຫດຫຼັກແມ່ນມາຈາກຄວາມຊັບຊ້ອນຂອງອັກສອນລາວ (ມີສະຫຼະເທິງ-ລຸ່ມ, ວັນນະຍຸດ), ຮູບແບບການຈັດລຽງທີ່ຊ້ອນກັນຫຼາຍແຖວ (ເຊັ່ນ: ໝວດອັກສອນ “ກທ” ແລະ ຕົວເລກໃນແຖວເທິງ, ພ້ອມກັບຊື່ແຂວງ “ນະຄອນຫຼວງວຽງຈັນ” ໃນແຖວລຸ່ມ).
ໃນບົດຄວາມນີ້, ເຮົາຈະມາເຈາະເລິກຂັ້ນຕອນການສ້າງ Pipeline ສຳລັບ ALPR ທີ່ອອກແບບມາເພື່ອປ້າຍທະບຽນລາວໂດຍສະເພາະ, ເລີ່ມຕັ້ງແຕ່ການເຮັດ Object Detection ສຳລັບຫາ Bounding Box ຈົນເຖິງການໃຊ້ Custom OCR ດ້ວຍສະຖາປັດຕະຍະກຳຂັ້ນສູງ.
ສະຖາປັດຕະຍະກຳຂອງລະບົບ (System Pipeline)
ເພື່ອໃຫ້ລະບົບສາມາດເຮັດວຽກໄດ້ຢ່າງມີປະສິດທິພາບແບບ Real-time ໃນສະພາບແວດລ້ອມຕົວຈິງ (ເຊັ່ນ: ກ້ອງ CCTV ຕາມສີ່ແຍກໄຟແດງ), ເຮົາຈະແບ່ງ Pipeline ອອກເປັນ 3 ພາກສ່ວນຫຼັກຄື:
- License Plate Detection: ກວດຈັບຕຳແໜ່ງຂອງປ້າຍທະບຽນ.
- Image Preprocessing: ປັບແຕ່ງຮູບພາບທີ່ຖືກຕັດໃຫ້ພ້ອມສຳລັບການອ່ານ.
- Optical Character Recognition (OCR): ສະກັດເອົາຕົວອັກສອນ ແລະ ຕົວເລກອອກມາເປັນ Text.
ຂັ້ນຕອນທີ 1: ການກວດຈັບປ້າຍທະບຽນດ້ວຍ YOLOv8
YOLO (You Only Look Once) ເວີຊັ່ນ 8 ຖືວ່າເປັນ State-of-the-Art (SOTA) ສຳລັບ Object Detection ທີ່ໃຫ້ຄວາມສົມດຸນທີ່ດີທີ່ສຸດລະຫວ່າງຄວາມໄວ (Inference FPS) ແລະ ຄວາມແມ່ນຍຳ. ສຳລັບປະເທດລາວ, ປ້າຍລົດມີຫຼາຍສີ (ປ້າຍເຫຼືອງ, ປ້າຍຂາວ, ປ້າຍຟ້າ) ແລະ ຫຼາຍຂະໜາດ. ດັ່ງນັ້ນ, ທ່ານຈຳເປັນຕ້ອງ Train ໂມເດວ YOLOv8 ດ້ວຍ Dataset ປ້າຍລົດລາວໂດຍສະເພາະ.
ຂ້າງລຸ່ມນີ້ແມ່ນຕົວຢ່າງຂອງການ Inference ເພື່ອດຶງເອົາພິກັດ (Bounding Box coordinates) ມາຕັດຮູບ (Crop) ສຳລັບຂັ້ນຕອນຕໍ່ໄປ:
from ultralytics import YOLO
import cv2
# ໂຫຼດໂມເດວ ທີ່ໄດ້ຜ່ານການ Fine-tune ດ້ວຍຮູບພາບປ້າຍລົດລາວແລ້ວ
model = YOLO('yolov8n_lao_plates.pt')
# ອ່ານຮູບພາບຈາກກ້ອງ CCTV ໃນວຽງຈັນ
original_img = cv2.imread('vientiane_traffic_cam.jpg')
results = model(original_img)
for r in results:
boxes = r.boxes
for box in boxes:
# ສະກັດເອົາພິກັດ x1, y1, x2, y2 ຂອງ Bounding Box
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy().astype(int)
# Crop ຮູບສະເພາະສ່ວນທີ່ເປັນປ້າຍທະບຽນ
plate_img = original_img[y1:y2, x1:x2]
# ສົ່ງຕໍ່ໄປຍັງຂັ້ນຕອນ Preprocessing
# process_plate(plate_img)
ຂັ້ນຕອນທີ 2: ການປະມວນຜົນຮູບພາບ (Advanced Image Preprocessing)
ເມື່ອທ່ານໄດ້ Bounding Box ແລ້ວ, ຮູບພາບທີ່ໄດ້ມັກຈະມີປັນຫາເຊັ່ນ: ມົວ, ແສງສະທ້ອນໃນຕອນກາງຄືນ, ຫຼື ມີຂີ້ຝຸ່ນ (ເຊິ່ງພົບເຫັນໄດ້ຫຼາຍຕາມສາຍທາງເລກທີ 13). ການເຮັດ Preprocessing ແມ່ນຫົວໃຈສຳຄັນກ່ອນສົ່ງຮູບເຂົ້າໂມເດວ OCR.
ການໃຊ້ວິທີ Otsu’s Thresholding ຮ່ວມກັບ Gaussian Blur ຈະຊ່ວຍແຍກຕົວອັກສອນ (Foreground) ອອກຈາກພື້ນຫຼັງປ້າຍ (Background) ໄດ້ຢ່າງຈະແຈ້ງ.
def preprocess_plate(plate_img):
# ປ່ຽນເປັນຮູບແບບ Grayscale
gray = cv2.cvtColor(plate_img, cv2.COLOR_BGR2GRAY)
# ໃຊ້ Gaussian Blur ເພື່ອລົບລ້າງສຽງລົບກວນ (Noise) ຈາກຂີ້ຝຸ່ນ ຫຼື ກ້ອງຄວາມລະອຽດຕ່ຳ
blur = cv2.GaussianBlur(gray, (5, 5), 0)
# ນຳໃຊ້ການແຍກແບບ Binarization ດ້ວຍ Otsu's Thresholding
_, binary = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return binary
ຂັ້ນຕອນທີ 3: ການສ້າງ Custom OCR ສຳລັບອັກສອນລາວ
ນີ້ຄືພາກສ່ວນທີ່ທ້າທາຍທີ່ສຸດ. ເນື່ອງຈາກອັກສອນລາວບໍ່ສາມາດພຽງແຕ່ຕັດ (Segment) ເປັນຕົວໆໄດ້ງ່າຍໆ ເພາະມັນມີການຊ້ອນກັນໃນແນວຕັ້ງ (ເຊັ່ນ: ໄມ້ກົງ, ໄມ້ໂທ). ວິທີການທີ່ດີທີ່ສຸດຄືການໃຊ້ CRNN (Convolutional Recurrent Neural Network) ຮ່ວມກັບ CTC (Connectionist Temporal Classification) Loss.
- CNN ຊ່ວຍໃນການດຶງ Features ຂອງຮູບພາບ (Feature Extraction).
- RNN (Bi-LSTM) ຊ່ວຍໃນການຮຽນຮູ້ລຳດັບຂອງຕົວອັກສອນ (Sequence Context) ວ່າຕົວອັກສອນໃດຄວນມາກ່ອນຫຼືຫຼັງ.
- CTC Loss ເປັນອັນກໍຣິທຶມທາງຄະນິດສາດ ທີ່ຊ່ວຍຈັດລຽງ (Align) ລຳດັບການທຳນາຍຂອງໂມເດວໃຫ້ກົງກັບໂຕໜັງສືຕົວຈິງ ໂດຍບໍ່ຈຳເປັນຕ້ອງບອກພິກັດແນ່ນອນຂອງແຕ່ລະຕົວອັກສອນໃນຕອນກຽມຂໍ້ມູນ.
ຕົວຢ່າງການກຳນົດ CTC Loss ໃນ PyTorch ສຳລັບການຝຶກສອນ (Training) ໂມເດວ:
import torch
import torch.nn as nn
# ສົມມຸດວ່າເຮົາລວມຕົວອັກສອນລາວທັງໝົດ, ຕົວເລກ ແລະ ຊື່ແຂວງ (Vocab size)
# Blank index ແມ່ນຈຳເປັນສຳລັບ CTC
ctc_loss = nn.CTCLoss(blank=0, zero_infinity=True)
# log_probs: Output ທີ່ໄດ້ຈາກໂມເດວ CRNN (ຮູບແບບ: Length x Batch x Classes)
# targets: ລຳດັບຕົວອັກສອນທີ່ເປັນ Ground Truth ຂອງປ້າຍທະບຽນນັ້ນ
loss = ctc_loss(log_probs, targets, input_lengths, target_lengths)
# ດຳເນີນການ Backpropagation ເພື່ອອັບເດດນ້ຳໜັກຂອງໂມເດວ
loss.backward()
Optimization Tip: ເພື່ອໃຫ້ລະບົບນຳໄປໃຊ້ງານຈິງໄດ້ດີ, ຄວນແບ່ງການທຳນາຍ OCR ອອກເປັນ 2 ໂມເດວ ຫຼື ກຳນົດ ROI (Region of Interest) ສອງສ່ວນແຍກກັນຄື: ສ່ວນເທິງສຳລັບຕົວອັກສອນ+ຕົວເລກ (ເຊັ່ນ: ບກ 9999) ແລະ ສ່ວນລຸ່ມສຳລັບການອ່ານຊື່ແຂວງ.
Key Takeaways
- YOLOv8 ແມ່ນທາງເລືອກທີ່ດີທີ່ສຸດໃນປັດຈຸບັນສຳລັບການເຮັດ License Plate Detection ເພາະໃຫ້ຄວາມໄວຕອບສະໜອງໄດ້ດີໃນກ້ອງວິດີໂອ.
- Contextual Preprocessing ແມ່ນຂາດບໍ່ໄດ້. ການຫຼຸດຜ່ອນ Noise ຈາກສະພາບປ້າຍໃນລາວດ້ວຍ Gaussian Blur ແລະ Otsu’s Thresholding ຈະຊ່ວຍເພີ່ມຄວາມແມ່ນຍຳໃຫ້ OCR ໄດ້ເຖິງ 30%.
- CRNN + CTC Loss ຖືກອອກແບບມາເພື່ອແກ້ໄຂບັນຫາ Sequence Detection ທີ່ຊັບຊ້ອນ, ເຊິ່ງເໝາະສົມກັບຮູບແບບອັກສອນລາວທີ່ມີການຈັດວາງທັງແນວນອນ ແລະ ແນວຕັ້ງຫຼາຍທີ່ສຸດ.
ການສ້າງລະບົບ Computer Vision ເພື່ອອ່ານປ້າຍທະບຽນລົດໃນລາວ ແມ່ນກໍລະນີສຶກສາທີ່ສະແດງໃຫ້ເຫັນວ່າ ເຕັກໂນໂລຊີ AI ລະດັບໂລກຕ້ອງຖືກນຳມາປະຍຸກຕາມບໍລິບົດຂອງທ້ອງຖິ່ນຈຶ່ງຈະເກີດປະໂຫຍດສູງສຸດ. ຈາກການແກ້ໄຂບັນຫາແສງເງົາຕາມທ້ອງຖະໜົນ ຈົນເຖິງການ Fine-tune ໂມເດວໃຫ້ເຂົ້າໃຈພາສາແມ່ຂອງເຮົາ, ທຸກໆຂັ້ນຕອນລ້ວນແຕ່ຕ້ອງການຮາກຖານທາງດ້ານວິສະວະກຳຊອບແວ ແລະ ຄະນິດສາດທີ່ແໜ້ນໜາ. ສິ່ງເຫຼົ່ານີ້ບໍ່ພຽງແຕ່ຊ່ວຍພັດທະນາລະບົບຈະລາຈອນໃນປະເທດເທົ່ານັ້ນ, ແຕ່ຍັງເປັນການຍົກລະດັບຂີດຄວາມສາມາດຂອງນັກພັດທະນາ AI ໃນລາວໃຫ້ກ້າວສູ່ມາດຕະຖານສາກົນໄດ້ອີກດ້ວຍ.