Python - Nhận dạng xe hơi với OpenCV

Trong bài này, mình sẽ hướng dẫn sử dụng OpenCV để nhận diện xe hơi trong ảnh (video frame) với đặc trưng haar, sử dụng file mô hình đã được trained.

Bài viết chỉ giúp hình dung code trên Opencv chứ không đi sâu vào thuật toán. Trong bài này mình sẽ hướng dẫn cách build/install opencv trên Ubuntu, một chương trình đơn giản detect 1 vùng ảnh, phân loại đó có phải xe hơi hay không và vẽ 1 hình chữ nhật đánh dấu.

Cài đặt OpenCV trên Ubuntu

Sử dụng Windows hay Fedora bạn có thể cài đặt dễ dàng theo hướng dẫn này, còn mình sử dụng Ubuntu nên phải build từ source.

Cài đặt trước một số package/thư viện để build opencv:

sudo apt-get install build-essential cmake pkg-config
sudo apt-get install libjpeg8-dev libtiff5-dev libjasper-dev libpng12-dev # image
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev # codec, video
sudo apt-get install libgtk-3-dev # opencv GUI
sudo apt-get install libatlas-base-dev gfortran

Download source từ Github, mình sử dụng version 3.1.0:

wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.1.0.zip
unzip opencv.zip
wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.1.0.zip
unzip opencv_contrib.zip

OpenCV yêu cầu dependency là numpy

pip install numpy

Bắt đầu build source:

cd opencv-3.1.0/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D INSTALL_PYTHON_EXAMPLES=ON \
    -D INSTALL_C_EXAMPLES=OFF \
    -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-3.1.0/modules \
    -D BUILD_EXAMPLES=ON ..

Note: Nếu trong quá trình build bị lỗi stdlib.h: No such file or directory thì chỉ cần tạo lại thư mục build, thêm tham số -D ENABLE_PRECOMPILED_HEADERS=OFF vào lệnh cmake

Sau khi build xong, để sử dụng được Python 2, bạn phải chú ý đường dẫn của Interpreter, Libraries, numpy, và packages path có chính xác hay không.

Sau khi Cmake không còn lỗi, bắt đầu build (-j4 là sử dụng 4 core để build)

make -j4

Bước cuối cùng, install vào OS:

sudo make install
sudo ldconfig

Đã xong, kiểm tra thử đã cài đặt thành công hay chưa:

Sau khi cài thành công, có thể xóa source nếu không cần thiết nữa:

rm -rf opencv-3.1.0 opencv_contrib-3.1.0 opencv.zip opencv_contrib.zip

Nhận dạng xe

Load thư viện opencv, nếu bạn sử dụng Jupyter notebook thì import cả matplotlib để hiển thị ảnh inline ngay trên cell output.

%matplotlib inline
import cv2

# Will use matplotlib for showing the image in notebook
# Sử dụng matplotlib để hiển thị ảnh trên notebook
from matplotlib import pyplot as plt

Tải cars.xml bỏ vào thư mục làm việc. Đây là Cascade Classifier ảnh. Kế tiếp đọc ảnh và chuyển sang chế độ màu gray.

Ta có ảnh sau:

car_cascade = cv2.CascadeClassifier('cars.xml')
img = cv2.imread('car3.jpg', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Sử dụng detectMultiScale để detect xe, sau đó vẽ border hình chữ nhật để đánh dấu vị trí trên ảnh.

# Detect cars
cars = car_cascade.detectMultiScale(gray, 1.1, 1)

# Draw border
for (x, y, w, h) in cars:
    cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2)
    ncars = ncars + 1

Cuối cùng hiển thị kết quả

# Show image
plt.imshow(img)

Test một số ảnh khác:

Source code đầy đủ chương trình trên:

import cv2
from matplotlib import pyplot as plt

car_cascade = cv2.CascadeClassifier('cars.xml')
img = cv2.imread('car3.jpg', 1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Detect cars
cars = car_cascade.detectMultiScale(gray, 1.1, 1)

# Draw border
for (x, y, w, h) in cars:
    cv2.rectangle(img, (x,y), (x+w,y+h), (0,0,255), 2)
    ncars = ncars + 1

# Show image
plt.figure(figsize=(10,20))
plt.imshow(img)

Kết quả nhận dạng phụ thuộc nhiều vào Cascade cars.xml đã train trước, nên có thể kết quả nhận diện không hoàn toàn chính xác.

Tham khảo: