Giới thiệu

Phát hiện ngón tay là một tác vụ khá thú vị trong lĩnh vực xử lý hình ảnh, đặc biệt là khi được ứng dụng trong các tương tác giữa người và máy. Trong bài viết này, ta sẽ mô tả cách để phát hiện số ngón tay xuất hiện trong video quay bằng camera laptop.

Tổng quan

Về cơ bản, bước đầu tiên, cũng là bước khó khăn nhất, là phát hiện tay trong khung video. Cách thức được nêu trong bài là sử dụng phối hợp Background Subtraction (Loại bỏ nền) và HSV Segmentation (Phân khúc HSV) để tạo mask. Sau khi phần tay đã được phân khúc, ta sẽ bắt đầu thực hiện phát hiện số ngón tay được giơ trong video. Để làm điều này, có 2 cách. Thứ nhất, ta sẽ tìm khối lớn nhất trong ảnh, tạm giả định khối này là bàn tay. Sau đó, ta sẽ tìm vùng bao lồi (convex hull) và các sai lệch lồi (convexity defect) – chủ yếu là khoảng cách giữa các ngón tay. Còn ở cách thứ hai, ta sẽ sử dụng một mạng nơ-ron tích chập cùng với đầu vào là mask để xác định số ngón tay. Mã nguồn của mạng nơ-ron này có thể được lấy tại đây.

Phát hiện bàn tay

Phát hiện bàn tay là bước khó nhất trong toàn bộ quá trình, và đồng thời có rất nhiều cách tiếp cận khác nhau. Một số ví dụ nổi bật là Background Subtraction của Izone, HSV Segmentation của Amar Prakash Pandey, Haar Cascade, và mạng nơ-ron. Bài viết này sẽ chỉ nói về các phương pháp Background Subtraction và HSV Segmentation.

Background subtraction

Trước hết, ta cần có hình nền không có bàn tay. Sau đó, để phát hiện phần nào của ảnh là bàn tay, ta sẽ loại bỏ phần có chưa bàn tay ra khỏi nền ảnh. Điều có thể được thực hiện một cách dễ dàng thông qua OpenCV.

Trong đây sẽ chỉ nêu một phần code để lý giải cách thức hoạt động. Phần code đầy đủ có thể được lấy tại đây.

Tại bước thứ nhất, ta cần tạo một hệ loại bỏ nền trong trường hợp ảnh không tồn tại bàn tay.

Dưới đây là kết quả thu được sau quy trình.

Trong đó, phần nền đã bị che bởi mask.

Tuy nhiên, cách thức này lại có một nhược điểm lớn, đó là nếu chỉ sử dụng nó, thì các vật chuyển động khác cũng sẽ bị giữ lại. Do vậy, bài viết sẽ tiếp tục giới thiệu thêm một phương pháp khác.

HSV segmentation

HSV trong tên phương thức này là viết tắt của H – Hue, S – Saturation, và V – Value, trong đó phần bàn tay sẽ được tách khỏi ảnh dựa trên màu sắc. Trước hết, ta sẽ lấy mẫu màu của bàn tay. Sau đó, ta sẽ thử phát hiện màu đó. Thông thường, một pixel trong ảnh/khung ảnh sẽ được hiển thị dưới dạng RGB (Đỏ, Xanh lá, Xanh dương). Ở đây, ta sẽ dùng HSV thay vì RGB, do RGB chứa các thông tin liên quan đến độ sáng của màu sắc. Vì vậy, khi lấy mẫu màu của bàn tay, ta cũng sẽ phải lấy mẫu độ sáng. Điều này sẽ gây khó khăn cho việc phát hiện, do bàn tay sẽ phải có cùng độ sáng thì ta mới phát hiện được. Do vậy, ta sẽ chỉ lấy mẫu màu dựa vào Hue (H) và Saturation (S).

Dựa vào kỹ thuật của Amar, ta sẽ để tay vào một vị trí cụ thể để lấy mẫu màu của nó. Sau đó, sử dụng các pixel màu này, ta sẽ tạo ra một biểu đồ tần suất về tần suất xuất hiện của từng màu trong ảnh, từ đó tìm được phân phối xác suất của các màu. Sau đó, ta sẽ chuẩn hóa biểu đồ tần suất trên để xem mỗi màu này có xác suất thuộc về bàn tay là bao nhiêu.

Đối số [0,1] sẽ chỉ lấy thông tin về Hue và Saturation, bỏ qua Value.

Đối số [0, 180, 0, 256] chỉ rõ khoảng giá trị của Hue và Saturation. Trong đó, Hue nằm trong khoảng từ 0 tới 179, còn Saturation nằm trong khoảng từ 0 tới 255.

Sau khi có được biểu chuẩn hóa về các màu bàn tay, ta sẽ có thể tạo ra mask HSV – trên thực chất là bản đồ xác suất. Mỗi pixel trên bản đồ này sẽ chứa thông tin về xác suất thuộc về bàn tay của pixel đó.

Dưới đây là kết quả thu được sau khi thực hiện HSV segmentation.

Nhược điểm của phương pháp này là nó sẽ thực hiện phát hiện cả màu da, trong khi ta lại chỉ muốn lọc phần bàn tay. Do vậy, ta sẽ sử dụng phương trình “bitwise and” trên mask nền trước và mask HSV. Kết quả thu được sau khi ứng dụng phương trình sẽ là kết quả cuối cùng.

Đếm số ngón tay

Sau khi có được mask, ta sẽ bắt đầu thực hiện đếm số ngón tay. Cụ thể, ta có 2 phương pháp: 1 là phương pháp thủ công thông qua việc phát hiện các chênh lệnh về độ lồi (convexity defect), và 2 là sử dụng mạng nơ-ron tích chập.

Phương pháp thủ công

Xanh lá: Khối (contour)
Đỏ: Bao lồi (convex hull)
Xanh dương: chênh lệch độ lồi (convexity defect)

Sau khi phân tách, mask sẽ chỉ lưu lại phần bàn tay. Do đó, trong phương thức thủ công, ta trước tiên sẽ tìm vùng khối lớn nhất – được giả định là chính bàn tay này.

Sau khi tìm được khối, ta sẽ tiếp tục tìm bao lồi – tức phần hình cong bao hàm khối vừa tìm. Từ bao lồi, ta có thể thấy các chênh lệch độ lồi – tức các phần bị lõm vào trong của bao lồi. Ở đây, các phần này sẽ được coi là khoảng trống giữa các ngón tay, mà từ đó, ta có thể xác định số ngón tay được giơ lên trong hình.

Trong quá trình đếm các khoảng chênh lệch lồi, ta sẽ phải đặt một vài hạn chế, nhằm loại bỏ các khoảng thừa, đặc biệt là nếu khối bị xiêu vẹo. Một trong các hạn chế này là độ sâu của khoảng (trong ví dụ là là phải lớn hơn 10000), giúp loại bỏ các vùng lõm nhẹ có khả năng cao là không phải ngón tay. Ngoài ra, các khoảng có góc rộng hơn 90% cũng bị loại bỏ. Ở trường hợp này, góc sẽ được tính sử dụng côsin.

Sau khi thực hiện quy trình, ta sẽ thu được số lượng khoảng lõm, từ đó xác định được số ngón tay. Ví dụ: Có 2 khoảng lõm thì có 3 ngón tay đang được giơ. Tuy nhiên, nhược điểm của phương thức này là sẽ không có khác biệt khi số ngón tay giơ lên là 0 và 1. Điều này có thể được giải quyết bằng cách tính khoảng cách giữa tâm khối và điểm cao nhất của khối. Nếu khoảng cách này vượt một giới hạn nhất định, thì số ngón tay là 1, còn nếu không, thì đang không có ngón nào giơ lên.

Mạng nơ-ron tích chập

Sử dụng mạng nơ-ron tích chấp (Convolutional Neural Network – CNN) sẽ giúp đơn giản hóa rất nhiều quy trình. Trong đó, lựa chọn Keras trong Python là một giải pháp tốt và tương đối đơn giản. Do hạn chế về bộ nhớ GPU, video được sử dụng trong bài viết đã được nén từ kích thước 260*260 xuống còn 28*28, còn trong điều kiện không hạn chế, video gốc cũng có thể được sử dụng làm đầu vào. Dưới đây là code xây dựng mô hình CNN trong bài.

Mô hình này đã được huấn luyện thông qua khoảng 1000 hình ảnh mỗi lớp, và 200 hình ảnh để kiểm thử. Ngoài ra, trong quá trình huấn luyện, các hình ảnh này đã bị xoay, xê dịch, và lật. Chi tiết hơn về quá trình huấn luyện được nêu cụ thể trong mã nguồn.

Số lượng các hình ảnh đã được cân đổi để hạn chế sai số trong mô hình.

Sau đây là một vài ví dụ của dữ liệu huấn luyện.

Kết quả khá khả quan: Độ chính xác ở khoảng thứ 5 đạt 99%. Tuy nhiên, mô hình này mới chỉ được huấn luyện và kiểm thử trên một mẫu tay duy nhất, và có thể không chuẩn hóa tốt khi sử dụng các mẫu khác. Do vậy, mô hình sẽ không được công bố, mà thay vào đó, bạn có thể tự tạo dự liệu huấn luyện thông qua chức năng chụp ảnh bàn tay.

 

 

 

 

 

 

Và cuối cùng, mô hình sẽ được chạy thử và cho dự đoán kết quả như sau.

Kết luận

Kết quả phát hiện trên có thể được sử dụng làm lệnh tương tác với máy tính, và thậm chí là nhiều hơn nữa. Tuy nhiên, ứng dụng này còn cần được cải thiện rất nhiều trước khi có thể áp dụng được trên thực tế.

Tham khảo

  1. lzane/Fingers-Detection-using-OpenCV-and-Python. Retrieved from https://github.com/lzane/Fingers-Detection-using-OpenCV-and-Python
  2. amarlearning/Finger-Detection-and-Tracking. Retrieved from https://github.com/amarlearning/Finger-Detection-and-Tracking

FPT TechInsight
Theo Becominghuman.ai

Tin liên quan: