THUẬT TOÁN NHẬN DIỆN KHUÔN MẶT - FACE DETECTION SỬ DỤNG OPENCV

Uniduc JSC - 2020-03-23 12:09:34 | 2007 lượt xem

Mục lục

Ngày nay, Face detection luôn là một chủ đề thú vị, chủ yếu là vì kết quả rất trực quan - và nó không cần nhiều trí tưởng tượng để hiểu cách face detection có thể được sử dụng trong các ứng dụng trong thế giới thực. Từ hệ thống an ninh gia đình, đến giám sát, hoặc chỉ đơn giản là điều khiển TV của bạn, nhận diện khuôn mặt là một phần quan trọng của thị giác máy tính. Và hôm nay, chúng ta có thể khám phá cách thức mà nó thực hiện trong OpenCV.

Thuật toán Viola-Jones

Thuật toán Viola-Jones lần đầu tiên được xuất bản vào năm 2001 bởi Paul Viola và Michael Jones trong bài báo năm 2001 của họ, Rapid Object Detection using a Boosted Cascade of Simple Features, bài báo này đã trở thành một trong những bài báo được trích dẫn nhiều nhất trong tài liệu về computer vision. Trong bài báo này, Viola và Jones đề xuất một thuật toán có khả năng phát hiện các vật thể trong hình ảnh, bất kể vị trí và tỷ lệ của chúng trong một hình ảnh. Hơn nữa, thuật toán này có thể chạy trong thời gian thực, giúp phát hiện các đối tượng trong video stream.

Cụ thể, Viola và Jones tập trung vào việc phát hiện khuôn mặt trong ảnh, nhưng thuật toán này cũng có thể được sử dụng để huấn luyện máy dò tìm các vật thể tùy ý, như xe hơi, tòa nhà, dụng cụ nhà bếp và thậm chí là một trái chuối.

Mặc dù khung Viola-Jones chắc chắn đã mở ra cánh cửa để phát hiện đối tượng, nhưng giờ đây nó đã vượt xa các phương pháp khác, chẳng hạn như sử dụng Histogram of Oriented Gradients (HOG) + Linear SVM và Deep Learning  Nhưng mình vẫn nghĩ rằng điều quan trọng là chúng ta rất quan tâm đến thuật toán này và ít nhất là có sự hiểu biết ở mức độ cao về những gì mà diễn ra bên dưới.

Nhớ lại Kernel Image và cách chúng ta trượt một ma trận nhỏ trên hình ảnh của chúng ta từ trái sang phải và từ trên xuống dưới, tính toán một giá trị đầu ra cho mỗi pixel trung tâm của kernel? Chà, hóa ra cách tiếp cận cửa sổ trượt này cũng cực kỳ hữu ích trong bối cảnh phát hiện các đối tượng trong một hình ảnh:

Trong hình trên, chúng ta có thể thấy rằng chúng ta đang trượt một cửa sổ kích thước cố định trên hình ảnh của chúng ta ở nhiều tỷ lệ. Tại mỗi giai đoạn này, cửa sổ của chúng ta dừng lại, tính toán một số tính năng và sau đó phân loại khu vực là có khuôn mặt hay không.

Rõ ràng, điều này đòi hỏi một chút về machine learning. Chúng ta cần một bộ phân loại được đào tạo sử dụng các mẫu positive và negative của khuôn mặt. Điểm dữ liệu positive sẽ là các ví dụ khu vực có chứa một khuôn mặt. Các điểm dữ liệu negative sẽ là ví dụ về các vùng không chứa khuôn mặt. Dựa vào những điểm dữ liệu này, chúng ta có thể đào tạo một bộ phân loại để nhận biết liệu một vùng nhất định của hình ảnh có chứa một khuôn mặt hay không.

May mắn thay cho chúng tôi, OpenCV có thể thực hiện phát hiện khuôn mặt bằng cách sử dụng Haar cascade được đào tạo trước:

Điều này đảm bảo rằng chúng ta không cần phải cung cấp các mẫu positive và negative của riêng mình, huấn luyện bộ phân loại riêng của chúng tôi hoặc lo lắng về việc điều chỉnh các tham số chính xác. Thay vào đó, chúng ta chỉ cần tải lên trình phân loại được đào tạo trước và phát hiện khuôn mặt trong ảnh.

Đối với mỗi điểm dừng dọc theo đường dẫn cửa sổ trượt, năm tính năng hình chữ nhật được tính:

Nếu bạn đã quen thuộc với wavelet, bạn có thể thấy rằng chúng có một số điểm tương đồng với các chức năng cơ bản Haar wavlet.

Để có được các tính năng cho từng khu vực trong năm hình chữ nhật này, chúng ta chỉ cần trừ tổng số pixel ở vùng trắng cho tổng số pixel ở vùng đen. Thật thú vị, các tính năng này có tầm quan trọng thực sự trong bối cảnh nhận diện khuôn mặt:

   - Vùng mắt có xu hướng tối hơn vùng má.
   - Vùng mũi sáng hơn vùng mắt.

Do đó, với năm vùng hình chữ nhật này, chúng ta có thể tạo thành các đặc điểm có thể phân loại các phần của khuôn mặt. Sau đó, đối với toàn bộ tập hợp các tính năng, chúng ta sẽ sử dụng thuật toán AdaBoost để chọn những tính năng tương ứng với các vùng trên khuôn mặt của hình ảnh.

Tuy nhiên, như bạn có thể tưởng tượng, sử dụng một cửa sổ trượt cố định và trượt nó trên mọi (x, y) của hình ảnh, tiếp theo là tính toán các Haar-like feature và cuối cùng thực hiện phân loại thực tế có thể tốn kém về mặt tính toán.

Để chống lại điều này, Viola và Jones đã đưa ra khái niệm về cascade hoặc stages. Tại mỗi điểm dừng dọc theo đường dẫn cửa sổ trượt, cửa sổ phải vượt qua một loạt các thử nghiệm trong đó mỗi thử nghiệm tiếp theo đắt hơn về mặt tính toán so với trước đó. Nếu bất kỳ một thử nghiệm thất bại, cửa sổ sẽ tự động bị loại bỏ.

Một số lợi ích của Haar cascade là họ rất nhanh trong việc tính toán các Haar-like features, do sử dụng hình ảnh tích hợp (còn được gọi là bảng tổng hợp). Chúng cũng rất hiệu quả để lựa chọn tính năng thông qua việc sử dụng thuật toán AdaBoost. Có lẽ quan trọng nhất, họ có thể phát hiện khuôn mặt trong hình ảnh bất kể vị trí hay quy mô của khuôn mặt. Cuối cùng, thuật toán Viola-Jones để phát hiện đối tượng có khả năng chạy trong thời gian thực.

Face detection trong OpenCV

Các bạn cùng xem qua code

 

import argparse
import cv2
import imutils
 
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--face", required=True, help="Path to where the face cascade resides")
ap.add_argument("-i", "--image", required=True, help="Path to where the image file resides")
args = vars(ap.parse_args())
 
# load the image and convert it to grayscale
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 
# load the face detector and detect faces in the image
detector = cv2.CascadeClassifier(args["face"])
 
# handle face detection for OpenCV 2.4
if imutils.is_cv2():
	faceRects = detector.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=5,
		minSize=(30, 30), flags=cv2.cv.CV_HAAR_SCALE_IMAGE)
 
# otherwise handle face detection for OpenCV 3+
else:
	faceRects = detector.detectMultiScale(gray, scaleFactor=1.05, minNeighbors=5,
		minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE)
 
print("I found {} face(s)".format(len(faceRects)))
 
# loop over the faces and draw a rectangle around each
for (x, y, w, h) in faceRects:
	cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
 
# show the detected faces
cv2.imshow("Faces", image)
cv2.waitKey(0)

Các bạn chạy thuật toán và xem kết quả nhé, ở đây mình sẽ show ra kết quả của mình

Chúc bạn thành đạt trong công việc và hạnh phúc trong cuộc sống!

UNIDUC - Chuyên Robot, Dây Chuyền Sản Xuất Công Nghiệp tự động

  • Địa chỉ: 22 Đường 54, Thảo Điền, Quận 2, TP Hồ Chí Minh, Việt Nam
  • Hotline Tư Vấn Miễn Phí: 089 6688 629 (Mr Đức)
  • Email: [email protected]
  • Website: https://uniduc.com/vi/

Đăng kí nhận tin mới



Đánh giá bài viết

0%

0 Tổng người đánh giá
5
0%
4
0%
3
0%
2
0%
1
0%