Python: Nhận Dạng Khuôn Mặt Với Dưới 25 Dòng Mã Python | V1Study

Mục lục bài viết:

  • OpenCV
    • Tầng trong thực tế
  • Cài đặt OpenCV
  • Tìm hiểu vê mã lệnh
  • Kiểm tra kết quả
    • Chuyện gì đã xảy ra?
  • Mở rộng sang Webcam

Trong bài viết này, chúng ta sẽ xem xét một cách đơn giản nhất để bắt đầu với việc nhận dạng khuôn mặt bằng Python và thư viện nguồn mở OpenCV.

Trước khi bạn đặt bất kỳ câu hỏi nào thì:

  1. Đừng bỏ qua bài viết và chỉ cần cố gắng chạy code. Bạn phải hiểu những gì code đã làm, không chỉ để chạy nó đúng cách mà còn để khắc phục sự cố.
  2. Đảm bảo sử dụng OpenCV v2.
  3. Có một webcam hoạt động để tập lệnh này có thể hoạt động bình thường.
  4. Xem lại các nhận xét (comment) và câu hỏi khác, vì câu hỏi của bạn có thể đã được giải quyết.

Cảm ơn bạn.

Lưu ý: Ngoài ra, hãy xem hướng dẫn cập nhật về nhận diện khuôn mặt bằng Python.

OpenCV

OpenCV là thư viện phổ biến nhất cho thị giác máy tính. Ban đầu được viết bằng C/C++, bây giờ nó cung cấp các ràng buộc cho Python.

OpenCV sử dụng thuật toán máy học để tìm kiếm khuôn mặt trong ảnh. Bởi vì khuôn mặt rất phức tạp, không có một bài kiểm tra đơn giản nào cho bạn biết nó có tìm thấy khuôn mặt hay không. Thay vào đó, có hàng ngàn mẫu nhỏ và các tính năng phải được khớp với nhau. Các thuật toán chia nhỏ nhiệm vụ nhận dạng khuôn mặt thành hàng nghìn nhiệm vụ nhỏ hơn, có kích thước vừa phải, mỗi nhiệm vụ đều dễ giải quyết. Các tác vụ này còn được gọi là bộ phân loại.

Đối với một cái gì đó như khuôn mặt, bạn có thể có 6.000 bộ phân loại trở lên, tất cả đều phải khớp để phát hiện một khuôn mặt (tất nhiên là trong giới hạn lỗi). Nhưng vấn đề nằm ở chỗ: để nhận diện khuôn mặt, thuật toán bắt đầu ở trên cùng bên trái của một bức ảnh và di chuyển xuống trên các khối dữ liệu nhỏ, nhìn vào từng khối, liên tục hỏi, “Đây có phải là khuôn mặt không? … Đây có phải là một khuôn mặt? … Đây có phải là một khuôn mặt không? ” Vì có 6.000 bài kiểm tra trở lên cho mỗi khối, bạn có thể có hàng triệu phép tính để thực hiện, điều này sẽ khiến máy tính của bạn ngừng hoạt động.

Để giải quyết vấn đề này, OpenCV sử dụng các tầng. Tầng (cascade) là gì? Câu trả lời tốt nhất có thể được tìm thấy trong từ điển: "a waterfall or series of waterfalls."

Giống như một loạt waterfall, tầng trong OpenCV chia vấn đề phát hiện khuôn mặt thành nhiều giai đoạn. Đối với mỗi khối, nó thực hiện một bài kiểm tra rất khó khăn và nhanh chóng. Nếu điều này được vượt qua, thì nó sẽ thực hiện một bài kiểm tra chi tiết hơn một chút, v.v. Thuật toán có thể có 30 đến 50 trong số các giai đoạn hoặc tầng này và nó sẽ chỉ phát hiện một khuôn mặt nếu tất cả các giai đoạn đều vượt qua.

Ưu điểm là phần lớn hình ảnh sẽ trả về âm trong vài giai đoạn đầu tiên, có nghĩa là thuật toán sẽ không lãng phí thời gian để kiểm tra tất cả 6.000 tính năng trên đó. Thay vì mất hàng giờ, nhận diện khuôn mặt giờ đây có thể được thực hiện trong thời gian thực.

Tầng trong thực tế

Tuy lý thuyết nghe có vẻ phức tạp nhưng trên thực tế thì khá dễ dàng. Bản thân các tầng chỉ là một loạt các tệp XML chứa dữ liệu OpenCV được sử dụng để phát hiện các đối tượng. Bạn khởi tạo mã của mình với tầng mà bạn muốn, và sau đó nó thực hiện công việc cho bạn.

Vì nhận diện khuôn mặt là một trường hợp phổ biến, nên OpenCV đi kèm với một số tầng tích hợp để phát hiện mọi thứ từ khuôn mặt, mắt cho đến tay và chân. Thậm chí có những tầng dành cho những thứ không phải của con người. Ví dụ, nếu bạn điều hành một cửa hàng chuối và muốn theo dõi những người ăn trộm chuối, bạn đã xây dựng một cửa hàng cho điều đó!

Cài đặt OpenCV

Trước tiên, bạn cần tìm đúng file cài đặt cho hệ điều hành của bạn.

Tôi thấy rằng cài đặt OpenCV là phần khó nhất của nhiệm vụ. Nếu bạn gặp các lỗi lạ không thể giải thích được, đó có thể là do xung đột thư viện, sự khác biệt 32/64 bit, v.v. Tôi thấy đơn giản nhất là chỉ cần sử dụng một máy ảo Linux và cài đặt OpenCV từ đầu.

Sau khi hoàn tất cài đặt, bạn có thể kiểm tra xem nó có hoạt động hay không bằng cách kích hoạt phiên Python và nhập:

>>> import cv2 >>>

Nếu bạn không gặp bất kỳ lỗi nào, bạn có thể chuyển sang phần tiếp theo.

Tìm hiểu về mã lệnh

Hãy chia nhỏ mã thực tế mà bạn có thể tải xuống từ repo. Lấy script face_detect.py, ảnh abba.png pic, và file XML haarcascade_frontalface_default.xml.

# Nhận các giá trị do người dùng cung cấp imagePath = sys.argv[1] cascPath = sys.argv[2]

Trước tiên, bạn chuyển vào hình ảnh và tên tầng (cascade) dưới dạng đối số dòng lệnh. Chúng ta sẽ sử dụng hình ảnh ABBA cũng như tầng mặc định để phát hiện khuôn mặt do OpenCV cung cấp.

# Tạo tầng haar faceCascade = cv2.CascadeClassifier(cascPath)

Bây giờ chúng ta tạo tầng và khởi tạo nó với tầng khuôn mặt của chúng ta. Thao tác này sẽ tải dòng khuôn mặt vào bộ nhớ để nó sẵn sàng sử dụng. Hãy nhớ rằng, tầng chỉ là một tệp XML chứa dữ liệu để phát hiện khuôn mặt.

# Đọc ảnh image = cv2.imread(imagePath) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

Ở đây chúng ta đọc hình ảnh và chuyển đổi nó sang thang độ xám (grayscale). Nhiều hoạt động trong OpenCV được thực hiện ở thang độ xám.

# Nhận diện khuôn mặt trong ảnh faces = faceCascade.detectMultiScale( gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags = cv2.cv.CV_HAAR_SCALE_IMAGE )

Chức năng này phát hiện khuôn mặt thực và là phần quan trọng của mã của chúng ta, vì vậy chúng ta hãy xem xét các tùy chọn sau:

  1. Hàm detectMultiScale là một hàm tổng quát để phát hiện các đối tượng. Vì ta đang gọi nó trên tầng khuôn mặt, nên đó là những gì nó phát hiện.
  2. Tùy chọn đầu tiên là hình ảnh thang độ xám.
  3. Thứ hai là scaleFactor. Vì một số khuôn mặt có thể gần máy ảnh hơn, nên chúng sẽ xuất hiện lớn hơn so với các khuôn mặt ở phía sau. Scaler factor sẽ bù đắp cho điều này.
  4. Thuật toán phát hiện sử dụng một cửa sổ chuyển động để phát hiện các đối tượng. minNeighbors sẽ xác định có bao nhiêu đối tượng được phát hiện gần đối tượng hiện tại trước khi nó khai báo khuôn mặt được tìm thấy. Trong khi đó thì minSize sẽ cung cấp kích thước của mỗi cửa sổ.

Lưu ý: Tôi đã lấy các giá trị thường được sử dụng cho các trường này. Trong thực tế, bạn sẽ thử nghiệm với các giá trị khác nhau cho kích thước cửa sổ, hệ số tỷ lệ, v.v. cho đến khi bạn tìm thấy giá trị phù hợp nhất với mình.

Hàm trả về một danh sách các hình chữ nhật mà nó tin rằng nó đã tìm thấy một khuôn mặt. Tiếp theo, chúng ta sẽ lặp lại nơi nó nghĩ rằng nó đã tìm thấy thứ gì đó.

print "Found {0} faces!".format(len(faces)) # Vẽ một hình chữ nhật quanh các khuôn mặt for (x, y, w, h) in faces: cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)

Hàm này trả về 4 giá trị: vị trí x và y của hình chữ nhật, chiều rộng và chiều cao của hình chữ nhật (w, h).

Chúng ta sử dụng các giá trị này để vẽ một hình chữ nhật bằng cách sử dụng hàm có sẵn là rectangle().

cv2.imshow("Faces found", image) cv2.waitKey(0)

Cuối cùng, ta hiển thị hình ảnh và chờ người dùng nhấn một phím.

Kiểm tra kết quả

Hãy thử đối chiếu với ảnh ABBA:

$ python face_detect.py abba.png haarcascade_frontalface_default.xml

Ví dụ về phát hiện khuôn mặt Python 1: Abba

Điều đó đã hiệu quả. Còn đối với ảnh này:

Ví dụ về phát hiện khuôn mặt Python 2: sai

Bạn thấy rằng có một hình chữ nhật đang không được vẽ quanh một khuôn mặt. Hãy thử lại lần nữa. Tôi đã thay đổi các thông số và thấy rằng việc đặt scaleFactor thành 1,2 đã loại bỏ khuôn mặt sai.

Ví dụ về phát hiện khuôn mặt Python 2: đã sửa

Chuyện gì đã xảy ra?

Ta thấy rằng bức ảnh đầu tiên được chụp khá cận cảnh bằng máy ảnh chất lượng cao. Bức thứ hai dường như được chụp từ xa và có thể bằng điện thoại di động. Đây là lý do tại sao scaleFactor phải được sửa đổi. Như tôi đã nói, bạn sẽ phải thiết lập thuật toán trên cơ sở từng trường hợp để tránh "dương tính giả".

Hãy cảnh báo rằng vì điều này dựa trên máy học, nên kết quả sẽ không bao giờ chính xác 100%. Bạn sẽ nhận được kết quả đủ tốt trong hầu hết các trường hợp, nhưng đôi khi thuật toán sẽ xác định các đối tượng không chính xác là khuôn mặt.

Mã cuối cùng có thể được tìm thấy ở đây.

Mở rộng sang Webcam

Nếu bạn muốn sử dụng webcam thì sao? OpenCV lấy từng khung hình từ webcam và sau đó bạn có thể phát hiện khuôn mặt bằng cách xử lý từng khung hình.

Cập nhật: Bài viết tiếp theo được phát trực tiếp. Kiểm tra tính năng Nhận diện khuôn mặt trên Webcam bằng Python!

Từ khóa » Nhận Diện Python