41
Khởi động camera
Đầu tiên ta sẽ thiết lập một camera để thu nhận hình ảnh đầu vào. Để truy cập vào camera, ta cần dùng thư viện imutils – một bộ các chức năng xử lý hình ảnh giúp làm việc trên OpenCV dễ dàng hơn.
Lấy ảnh từ camera và xử lý
Ảnh sẽ được lấy trực tiếp từ camera. Tuy nhiên chương trình đòi hỏi ảnh đầu vào phải ở dạng mức xám. Do đó, tất cả ảnh màu đầu vào sẽ được chuyển hết về dạng mức xám với câu lệnh trong OpenCV như sau:
gray=cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY).
Phát hiện khuôn mặt
OpenCV đã tích hợp nhiều bộ phân loại (cascade) đã được huấn luyện cho việc nhận dạng các đối tượng như khuôn mặt, đôi mắt, nụ cười ... Đó là những file XML được lưu trữ trong thư mục “opencv / data / haarcascades”.
Đầu tiên chúng ta cần phải load các phân loại (cascade) XML cần thiết. Ở đây chúng ta cần bộ phân loại để huấn luyện cho khuôn mặt như sau:
haarcascade_frontalface_alt.xml: bộ dữ liệu huấn luyện (training) cho quá trình xử lý phát hiện khuôn mặt.
Ta có thể truy cập đường link sau để dowdload:
https://github.com/opencv/opencv/tree/master/data/haarcascades Lưu ý: tệp XML này phải nằm chung thư mục với file chương trình.
Đánh dấu cấu trúc khuôn mặt dùng Facial Landmarks
Bước tiếp theo là áp dụng thuật toán đánh dấu cấu trúc với 68 điểm trên vùng mặt của thư viện dlib để định vị từng khu vực quan trọng trên khuôn mặt. Các khu vực đó bao gồm: mày, mắt, mũi, miệng và đường viền khuôn mặt.
42 Máy dò mốc trên khuôn mặt được đào tạo trước bên trong thư viện dlib được sử dụng để ước tính vị trí của 68 tọa độ (x, y) ánh xạ đến các cấu trúc trên khuôn mặt.
Ta có thể truy cập đường link sau để dowdload: https://github.com/davisking/dlib-
models/blob/master/shape_predictor_68_face_landmarks.dat.bz2
Trích xuất vùng mắt và miệng
Mỗi mắt được biểu thị bằng 6 tọa độ (x, y), bắt đầu từ góc trái của mắt (với mắt trái được đánh dấu từ 37 đến 40 và mắt phải được đánh dấu từ 43 đến 46). Sử dụng phương pháp cắt mảng NumPy, chúng ta có thể trích xuất các tọa độ (x, y) của mắt trái và mắt phải.
Miệng được biểu diễn bởi một tập hợp 20 tọa độ (x.y), bắt đầu từ góc trái của miệng. Được chia thành 2 phần môi trên và môi dưới (với môi trên được đánh dấu từ 49 đến 60 và môi dưới được đánh dấu từ 61 đến 68).
Sử dụng phương pháp cắt mảng NumPy, chúng ta có thể trích xuất các tọa độ (x, y) của mắt trái, mắt phải và miệng.
Tính toán tỉ lệ mắt (EAR)
Mỗi mắt được biểu thị bằng 6 tọa độ (x, y), bắt đầu từ góc trái của mắt, sau đó làm việc theo chiều kim đồng hồ xung quanh phần còn lại của vùng:
Hình 36: Điểm mốc trên khuôn mặt liên quan đến mắt Dựa vào hình ảnh trên, chúng ta rút ra được 2 điểm chính:
43 -Có một mối quan hệ giữa chiều rộng và chiều cao của các tọa độ này -Dựa trên công trình của Soukupová và Čech trong bài báo năm 2016, chúng ta có thể rút ra một phương trình phản ánh mối quan hệ này được gọi là tỷ lệ khung hình của mắt (EAR) [3]:
Hình 37: Phương trình tỷ lệ khung hình của mắt
Trong đó p1 đến p6 là các vị trí đánh dấu mốc trên mắt. Tử số của phương trình này tính khoảng cách giữa các điểm mốc dọc trong khi mẫu số tính khoảng cách giữa các điểm mốc ngang, trọng số mẫu số bằng 2 là thích hợp vì chỉ có một tập các điểm ngang mà có hai bộ điểm thẳng đứng.
Tỷ số mắt là khoảng không đổi trong khi mắt mở, nhưng sẽ nhanh chóng giảm xuống gần bằng 0 khi một nháy mắt diễn ra.
Sử dụng phương trình đơn giản này, chúng ta có thể tránh các kỹ thuật xử lý hình ảnh và chỉ đơn giản dựa vào tỷ lệ khoảng cách mốc thời gian để xác định xem một mắt đang nhắm hay không.
Để làm cho điều này rõ ràng hơn, hãy xem xét các con số sau đây từ Soukupová và Čech:
44 Ở phía trên bên trái của hình, chúng ta có một mắt hoàn toàn mở - tỉ lệ mắt ở đây sẽ lớn và tương đối ổn định theo thời gian.
Tuy nhiên, một khi mắt nhấp nháy (phía trên bên phải hình) tỷ lệ mắt giảm đáng kể gần bằng không.
Phát hiện ngủ gật
Chúng ta bắt đầu phát hiện ngủ gật bằng việc thiết lập trước các giá trị:
- Ngưỡng của mắt (eye_threshold) để nhận dạng trạng thái mắt nhắm hay mở. - Biến đếm (blink_couter) là tổng số khung liên tiếp mà người đó đã nhắm mắt. - Số khung hình mà mắt nhắm liên tiếp (eye_frame) để nhận biết tài xế đang ngủ
gật hay chỉ là chớp mắt thông thường.
Tiếp đến chúng ta kiểm tra tỷ lệ mắt EAR đã được tính có dưới ngưỡng “eye_threshold” hay không để xác định mắt đóng hoặc mở. Nếu tỷ số mắt EAR được xác định nhỏ hơn ngưỡng “eye_threshold” thì tăng biến đếm “blink_couter”. Nếu “blink_couter” vượt quá số khung hình “eye_frame” đã đặt trước thì chúng ta giả định rằng người đó đang ngủ gật và bắt đầu bật cảnh báo. Ngược lại nếu tỷ số mắt lớn hơn ngưỡng mắt hoặc tổng số khung hình mắt nhắm liên tiếp không lớn hơn eye_frame” thì thiết lập lại “blink_couter” về ban đầu = 0 và tắt cảnh báo. Thực hiện lại công việc đó trong suốt quá trình thu hình để phát hiện tình trạng ngủ gật.
Tính toán tỷ lệ vùng miệng
Tương tự như với tỷ lệ mắt, vùng miệng được chia ra làm 20 tọa độ (x, y).
45 Ta tạo tỷ lệ khung hình miệng (MAR) tương tự như tỷ lệ mắt (EAR). Với công thức cho EAR như sau:
D = khoảng cách giữa p1 và p4.
L = trung bình của khoảng cách giữa p2 và p6; p3 và p5. 𝐸𝐴𝑅 = 𝐿 𝐷⁄ = ‖𝑃6 − 𝑃2‖ + ‖𝑃3 − 𝑃5‖
2‖𝑃1 − 𝑃4‖ (4.1) Còn đối với tỷ lệ vùng miệng (MAR), ta chia tỷ lệ như hình bên dưới.
Hình 40: Phân chia tỷ lệ vùng miệng Với D là khoảng cách giữa điểm 49 và 55.
L là khoảng cách trung bình giữa 51 và 59; 52 và 58; 53 và 57. Như vậy, ta có phương trình tỷ lệ vùng miệng MAR.
Hình 41: Phương trình MAR
Phát hiện ngáp
Tương tự như với phát hiện ngủ gật. Chúng ta sẽ bắt đầu bằng việc thiết lập trước các giá trị:
-Ngưỡng ngáp (yawn_threshold) để nhận dạng trạng ngáp hay đang nói chuyện bình thường.
46 -Biến đếm (yawn_couter) là tổng số khung hình liên tiếp mà người đó ngáp.
-Số khung hình (yawn) mà tỷ lệ vùng miệng (MAR) liên tiếp trên ngưỡng ngáp để tính là 1 lần ngáp.
Tiếp đến chúng ta kiểm tra tỷ lệ vùng miệng MAR đã được tính có trên ngưỡng ngáp “yawn_threshold” hay không để xác định người đó đang ngáp. Nếu tỷ số vùng miệng MAR được xác định lớn hơn ngưỡng “yawn_threshold” thì tăng biến đếm “yawn_couter”. Nếu “yawn_couter” vượt quá số khung hình “yawn” đã đặt trước thì chúng ta xác định là 1 lần ngáp và bật cảnh bảo trong 2s. Thực hiện lại công việc đó trong suốt quá trình thu hình để phát hiện tình trạng mất tập trung do ngáp ngủ.
Cảnh báo
Sau khi đã xác định tài xế có ngủ gật hoặc mất tập trung ta sẽ bật âm thanh để cảnh báo.
Để thực sự phát báo động WAV / MP3, ta cần thư viện pygame. Thư viện pygame được cài đặt thuận tiện qua pip lệnh “pip install pygame”.