Nhận diện khuôn mặt (Face Detection) là công nghệ được dùng để xác định khuôn mặt người từ những bức ảnh hoặc băng hình (images or videos). Công nghệ này được sử dụng rất rộng rãi trong cuộc sống với một số ứng dụng tiêu biểu như tag ảnh bạn bè trên facebook, lấy nét trên máy ảnh, tìm ảnh nghi phạm từ camera an ninh, …

Nhận diện khuôn mặt trên Iphone 6

Trong các mô hình nhận diện khuôn mặt thì mô hình Haar Cascade được coi là mô hình đầu tiên có khả năng chạy trong thời gian thực. Hãy cùng mình thử áp dụng mô hình trong bài hôm nay nhé.

Sơ lược về mô hình Haar Cascade

Haar Cascade được phát triển cách đây 20 năm và đạt tốc độ nhận diện khuôn mặt khoảng 15 ảnh trên 1 giây với máy tính có chip 700 Mhz Pentium III (chắc không có ai dùng con chip cổ này nữa, chip của laptop bây giờ cũng phải nhanh hơn mấy lần). Với sự thay đổi chóng mặt của công nghệ thì từ đó đến nay có rất nhiều mô hình khác được phát triển và có độ chính xác cao hơn. Tuy nhiên, mô hình Haar Cascade lại có điểm mạnh về tốc độ xử lý nhanh, nếu ứng dụng không cần độ chính xác quá cao thì đây chắc chắn là một trong những lựa chọn tốt nhất.

Ví dụ về phương pháp sliding window để tìm khuôn mặt cho từng khu vực nhỏ trên ảnh (nguồn: pyimagesearch)

Về cơ bản, mô hình Haar Cascade dùng phương pháp sliding-window (không biết nên dịch là gì nhỉ, cửa sổ trượt chăng?) để tìm khuôn mặt cho từng khu vực nhỏ trên ảnh. Với mỗi khu vực đó, các đặc trưng của ảnh (đặc trưng Haar) được trích xuất và áp dụng mô hình phân loại để xác định xem đó có phải là khuôn mặt người hay không.

Đặc trưng Haar (Haar features) và mô hình phân loại nhiều tầng (cascade classifier)

Thực hành

Thư viện OpenCV và Haar Cascade

Thư viện OpenCV đã bao gồm mô hình nhận diện khuôn mặt đã được huấn luyện, chúng ta có thể tải file mô hình về và áp dụng

Mô hình Haar Cascase đã được huấn luyện trong OpenCV (OpenCV Haar Cascade)

Trong bài hôm nay, chúng ta sẽ dùng mô hình nhận diện mặt người từ góc nhìn trực diện haarcascade_frontalface_default.xml. Mô hình này được dùng như sau:

  1. Load mô hình
    # load mô hình nhận diện khuôn mặt
    model_path = "models/haarcascade_frontalface_default.xml"
    detector = cv2.CascadeClassifier(model_path)
    
  2. Áp dụng mô hình
    # nhận diện khuôn mặt trong ảnh
    faces = detector.detectMultiScale(gray)
    print("Xác định được {} khuôn mặt".format(len(faces)))
    

    Hàm detectMultiScale nhận đầu vào (input) là ảnh đen trắng và trả về (output) toạ độ của các khuôn mặt.

Cấu trúc code

.
├── face_detection.py
├── images
│   └── vietnam_football_team.jpg
└── models
    └── haarcascade_frontalface_default.xml
  • File face_detection.py là file code chính được sử dụng
  • Thư mục images chứa các file ảnh
  • Thư mục models chứa mô hình tìm khuôn mặt người haarcascade_frontalface_default.xml

Để chạy mô hình cho một bức ảnh mới, chúng ta chỉ cần dùng đoạn code sau:

$ python face_detection.py --image [đường dẫn đến ảnh của bạn]

Sau đây là ví dụ với bức ảnh đội tuyển bóng đá Việt Nam

$ python face_detection.py --image images/vietnam_football_team.jpg
Ảnh đội tuyển Việt Nam, Asian Cup 2019 (By Fars News Agency, CC BY 4.0, Link)

Có thể thấy là mô hình 20 năm vẫn chạy tốt với 10 / 11 khuôn mặt cầu thủ được xác định đúng. Chúng ta vẫn có thể làm tốt hơn bằng cách tinh chỉnh các tham số khi áp dụng hàm detectMultiScale

faces = detector.detectMultiScale(gray, scaleFactor=1.03, minNeighbors=5, minSize=(10, 10), maxSize=(50, 50))
  • scaleFactor: phương pháp sliding window sẽ áp dụng nhiều window với cỡ khác nhau trên ảnh, tham số này quyết định tỷ lệ giữa kích thước giữa các window với nhau.
Ví dụ về các window với kích cỡ khác nhau theo Tỷ lệ kim tự tháp
  • minNeighbors: phương pháp sliding window thường sẽ xác định được vài window trên 1 khu vực ảnh, càng nhiều window xác định có khuôn mặt trong khu vực đó thì mô hình sẽ “tự tin hơn” đó là khuôn mặt. Tuy nhiên, giá trị này càng cao thì càng ít khuôn mặt được xác định.
  • minSize & maxSize: kích thước cho phép của vật thể (tối thiểu và tối đa). Tuỳ thuộc vào kích thước ảnh và khuôn mặt mà tinh chỉnh tham số này cho phù hợp.
Kết quả sau khi tinh chỉnh tham số

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# face_detection.py
import cv2
from argparse import ArgumentParser


# trích xuất đường dẫn ảnh (tham số khi chạy code)
parser = ArgumentParser(description="Apply Haar Cascade model on images")
parser.add_argument('--image', dest="image_path", help='Path to image', required=True)
args = parser.parse_args()
image_path = args.image_path

# load ảnh và chuyển sang ảnh đen trắng 
# (mô hình cần ảnh đen trắng đầu vào)
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
print("Load ảnh: {}".format(image_path))
print("Cỡ ảnh: {}".format(gray.shape))

# load mô hình nhận diện khuôn mặt
model_path = "models/haarcascade_frontalface_default.xml"
detector = cv2.CascadeClassifier(model_path)

# nhận diện khuôn mặt trong ảnh
faces = detector.detectMultiScale(gray)
print("Xác định được {} khuôn mặt".format(len(faces)))

# Vẽ đường bao cho từng khuôn mặt
green_color = (0, 255, 0)
for (x, y, w, h) in faces:
    cv2.rectangle(image, pt1=(x, y), pt2=(x + w, y + h), color=green_color, thickness=2)

# Hiển thị ảnh
cv2.imshow("Output Image with Face Detection", image)
cv2.waitKey(0)
  • Dòng 7 - 10: Trích xuất giá trị đường dẫn đến ảnh
  • Dòng 14 - 15: Đọc ảnh và chuyển sang ảnh đen trắng
  • Dòng 20 - 25: Load mô hình và áp dụng nhận diện khuôn mặt
  • Dòng 28 - 30: Vẽ đường bao (hình chữ nhật) cho từng khuôn mặt
  • Dòng 33 - 34: Hiển thị ảnh

Thảo luận

Mô hình Haar Cascade nhận diện khuôn mặt và đôi mắt (OpenCV documentation)

Tuy bài hôm nay tập trung vào nhận diện khuôn mặt nhưng thực ra mô hình Haar Cascade có thể được áp dụng cho bất kì trường hợp nào khác. Trong OpenCV có một vài mô hình đã được huấn luyện như nhận diện mắt người, nụ cười, mặt mèo … các bạn có thể tải mô hình từ OpenCV Haar Cascades và thử nghiệm. Trong trường hợp không tìm được mô hình có sẵn thì chúng ta có thể thu thập dữ liệu và xây dựng một mô hình mới cho riêng mình. Xây dựng một mô hình mới cũng khá thú vị, hẹn các bạn trong một bài khác để thảo luận về chủ đề này nhé.

Tham khảo

Leave a comment