Ứng dụng AI nhận diện biển báo giao thông là một bước tiến quan trọng trong lĩnh vực xe tự lái và các hệ thống hỗ trợ người lái (ADAS). Hệ thống này giúp phương tiện nhận biết biển báo như “Stop”, “Speed Limit” hoặc “No Entry” để xử lý tình huống kịp thời và tuân thủ luật giao thông. Công nghệ này đã xuất hiện trong nhiều nghiên cứu và sản phẩm thực tế, từ xe Tesla đến hệ thống cảnh báo trong các mẫu xe thông minh.
Nếu bạn từng quan tâm đến Phân loại ảnh trái cây bằng CNN đơn giản hoặc Phát hiện chuyển động trong video với OpenCV, thì việc triển khai AI nhận diện biển báo giao thông là bước tiếp theo để xây dựng các ứng dụng Computer Vision có tính ứng dụng cao. Bài viết này sẽ hướng dẫn từng bước, từ tải dữ liệu thật trên Kaggle đến huấn luyện mô hình CNN bằng TensorFlow.
Tập dữ liệu sử dụng
Chúng ta sẽ dùng dataset GTSRB – German Traffic Sign Dataset trên Kaggle, gồm hơn 50.000 hình ảnh biển báo thuộc 43 loại khác nhau. Dataset này đã được xử lý và sắp xếp sẵn, thuận tiện cho việc huấn luyện.
📦 Link tải dataset: GTSRB Dataset trên Kaggle
Cấu trúc dữ liệu:
| Cột | Ý nghĩa |
|---|---|
| Path | Đường dẫn tới file ảnh biển báo |
| ClassId | Nhãn lớp (0–42 tương ứng với 43 loại biển báo) |
| Width, Height | Kích thước ảnh |
| Roi.X1, Roi.Y1 | Tọa độ vùng chứa biển báo |
Nạp và khám phá dữ liệu
Bước đầu tiên là nạp dữ liệu và khám phá tổng quan để kiểm tra số lượng ảnh, phân phối nhãn và hiển thị một số hình ảnh mẫu. Điều này giúp bạn hiểu rõ dataset và phát hiện sớm vấn đề như mất cân bằng lớp (class imbalance).
Dataset có sẵn file CSV chứa đường dẫn ảnh và nhãn tương ứng, rất tiện để xử lý với Pandas.
import pandas as pd
import matplotlib.pyplot as plt
import cv2
import os
# Đọc file nhãn
data = pd.read_csv('GTSRB/Train.csv')
print(data.head())
print(data['ClassId'].value_counts())
# Hiển thị 5 hình ảnh mẫu
plt.figure(figsize=(10,4))
for i in range(5):
img = cv2.imread(os.path.join('GTSRB', data['Path'][i]))
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.subplot(1,5,i+1)
plt.imshow(img)
plt.title(f"Class {data['ClassId'][i]}")
plt.axis('off')
plt.show()
Tiền xử lý dữ liệu
Các mô hình CNN yêu cầu ảnh đầu vào có kích thước cố định. Chúng ta sẽ resize tất cả ảnh về 32×32 và chuẩn hóa pixel về [0,1]. Ngoài ra, nhãn sẽ được chuyển sang one-hot encoding để dùng cho bài toán phân loại nhiều lớp.
Đây là bước quan trọng để đảm bảo dữ liệu sẵn sàng cho quá trình huấn luyện.
import numpy as np
from sklearn.model_selection import train_test_split
from tensorflow.keras.utils import to_categorical
imgs, labels = [], []
for idx, row in data.iterrows():
img = cv2.imread(os.path.join('GTSRB', row['Path']))
img = cv2.resize(img, (32, 32))
imgs.append(img)
labels.append(row['ClassId'])
X = np.array(imgs) / 255.0 # Chuẩn hóa
y = to_categorical(labels, num_classes=43)
# Chia train/test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
Xây dựng và huấn luyện mô hình CNN
Chúng ta sẽ xây dựng một mạng CNN cơ bản gồm các lớp Conv2D, MaxPooling2D và Dense. Kiến trúc này đủ tốt để phân loại các biển báo trong dataset GTSRB. Bạn có thể mở rộng bằng ResNet hoặc MobileNet để đạt độ chính xác cao hơn.
Mô hình sẽ được huấn luyện trong 10 epoch để minh họa nhanh, nhưng bạn có thể tăng số epoch để cải thiện.
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
model = Sequential([
Conv2D(32, (3,3), activation='relu', input_shape=(32,32,3)),
MaxPooling2D(2,2),
Conv2D(64, (3,3), activation='relu'),
MaxPooling2D(2,2),
Flatten(),
Dense(128, activation='relu'),
Dropout(0.5),
Dense(43, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.summary()
# Huấn luyện
history = model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))
Đánh giá mô hình
Đánh giá mô hình trên tập test giúp bạn biết độ chính xác và khả năng tổng quát hóa của mô hình. Ngoài ra, trực quan hóa biểu đồ loss và accuracy theo epoch giúp phát hiện overfitting.
# Đánh giá
loss, acc = model.evaluate(X_test, y_test)
print(f"Độ chính xác trên tập test: {acc*100:.2f}%")
# Biểu đồ
plt.plot(history.history['accuracy'], label='Train Acc')
plt.plot(history.history['val_accuracy'], label='Val Acc')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
Kết luận
Bạn đã xây dựng thành công một hệ thống AI nhận diện biển báo giao thông bằng TensorFlow và OpenCV với dataset GTSRB. Hệ thống này có thể nhận diện 43 loại biển báo khác nhau và là nền tảng để phát triển ứng dụng trong xe tự lái hoặc giám sát giao thông.
Bạn có thể nâng cấp mô hình bằng cách thử nghiệm các kiến trúc CNN phức tạp hơn hoặc fine-tune từ mô hình pre-trained. Ngoài ra, tích hợp OpenCV để xử lý video trực tiếp sẽ biến đây thành một ứng dụng thực tế mạnh mẽ.

