Để cài đặt thư viện OpenCV cho RPi ta thức hiện theo các bước như sau:
Bước 1: Kết nối RPi với Internet thông qua cáp Ethernet hoặc dongle USB Wifi. Bước 2: Chạy lệnh sau để khởi động lại dịch vụ mạng.
Sudo service networking restart
Bước 3: Đảm bảo rằng Raspberry Pi được kết nối với Internet bằng cách nhập lệnh sau:
Ping -c4 www.google.com
Nếu lệnh này không chạy thành công thì chúng ta cần kiểm tra lại kết nối internet của Pi (có thể do dây cáp bị lỏng) rồi giải quyết sự cố. Sau đó, lặp lại các bước ở trên.
33 Bước 4: Chạy lần lượt các lệnh sau đây:
Sudo apt-get update
Lệnh này đồng bộ hóa danh sách gói từ nguồn. Chỉ mục của tất cả các gói được làm mới. Lệnh này phải được đưa ra trước khi thực hiện lệnh nâng cấp.
Sudo apt-get upgrade
Thao tác này sẽ cài đặt các phiên bản mới nhất của phần mềm đã được cài đặt. Các gói / tiện ích lỗi thời không tự động bị xóa. Nếu phần mềm được cập nhật, thì nó vẫn như vậy.
Sudo rpi-update
Lệnh này được sử dụng để nâng cấp phần sụn.
Bước 5: Bây giờ, chúng ta sẽ cần cài đặt một vài gói và phụ thuộc cần thiết cho OpenCV. Sau đây là danh sách các gói cần cài đặt. Chúng ta chỉ cần kết nối Pi với Internet và gõ lệnh:
sudo apt-get install <packagename> -y
34 Hình 29: Danh sách gói cài đặt
Ví dụ, nếu muốn cài đặt x264, chỉ cần gõ sudo apt-get install x264.
Bước 6: Cuối cùng, cài đặt OpenCV cho Python bằng cách sử dụng lệnh sau:
sudo apt-get install python-opencv -y
Đây là cách dễ nhất để cài đặt OpenCV cho Python. Tuy nhiên, có một vấn đề với điều này. Các kho lưu trữ Raspbian có thể không phải lúc nào cũng chứa phiên bản mới nhất của OpenCV. Đối với Python API, phiên bản mới nhất sẽ luôn chứa nhiều hỗ trợ tốt hơn và nhiều chức năng hơn.
35 >>> import cv2
>>> print cv2.__version__
Hình 30: Kiểm tra version của OpenCV 3.4.2 Cài đặt thư viện Dlib
Bước 1: Cài đặt các điều kiện tiên quyết của dlib. Thư viện dlib yêu cầu 4 điều kiện tiên quyết:
-Boost
-Boost.Python -Cmake -X11
Chúng ta có thể cài đặt thông qua các lệnh sau:
$ Sudo apt-get update
$ Sudo apt-get install build-essential cmake $ Sudo apt-get install libgtk-3-dev
36 Bước 2: Cài đặt thư viện Dlib
Chúng ta có thể cài đặt thông qua lệnh:
Pip3 install dlib
Bước 3: Kiểm tra cài đặt
Chúng ta kiểm tra bằng lệnh sau: >>> import dlib
Nếu lệnh được thực hiện thì chúng ta đã cài đặt thành công thư viện.
3.5 Camera Pi
3.5.1 Lựa chọn Camera
Có hai loại Camera Pi khác nhau thường được dùng trong xử lý ảnh là: Camera Pi bình thường và Camera Pi Noir.
Có nhiều sự khác biệt đáng kể giữa hai loại camera. Vào ban ngày thì Camera Pi Noir cho hình ảnh thu được không được đẹp như Camera bình thường. Tuy nhiên, Camera Pi Noir lại hoạt động tốt hơn vào ban đêm khi có sự hổ trợ của ánh sáng hồng ngoại.
Vì tình trạng ngủ gật và mệt mỏi thường xảy ra vào ban đêm nên Camera Pi Noir là lựa chọn tốt nhất cho đề tài này.
3.5.2 Camera Pi Noir V2
37 Tháng 4/2016, cùng với sản phẩm Camera Module V2, Raspberry Pi Foundation cũng ra mắt sản phẩm Raspberry Pi Camera Module NoIR (hồng ngoại) V2 và sử dụng sensor Sony IMX219 8 Megapixel.
Raspberry Pi Camera Module NoIR V2 có một cảm biến 8-megapixel của Sony IMX219 (so với cảm biến 5-megapixel OmniVision OV5647 trên Camera Hồng ngoại cũ).
Camera Module NoIR V2 mang trong mình mọi tính năng, công dụng của Camera Module thông thường, tuy nhiên có 1 điểm khác biệt là nó không sử dụng bộ lọc hồng ngoại (NoIR = NoInfrared). Điều này có nghĩa là hình ảnh chụp bằng ánh sáng ban ngày sẽ nhìn hơi mờ, nhưng nó mang lại khả năng nhìn trong bóng tối với ánh sáng hồng ngoại. Nó là một sản phẩm hoàn hảo để quan sát vào ban đêm (như camera giám sát), chụp ảnh trong môi trường ánh sáng thấp (như hoàng hôn chẳng hạn).
Thông số kỹ thuật:
- Ống kính tiêu cự cố định.
- Cảm biến độ phân giải 8 megapixel cho khả năng chụp ảnh kích thước 3280 x 2464.
- Hỗ trợ video 1080p30, 720p60 và 640x480p90. - Kích thước 25mm x 23mm x 9mm.
- Trọng lượng chỉ hơn 3g.
- Kết nối với Raspberry Pi thông qua cáp ribbon đi kèm dài 15 cm. - Camera Module được hỗ trợ với phiên bản mới nhất của Raspbian.
3.5.3 Kết nối Camera Pi với Raspberry Pi
Có 2 cách để kích hoạt Camera Pi.
Cách 1: Trong môi trường Desktop, di chuyển đến cửa sổ Raspberry Pi Configuration trong trình đơn preferences, mở tab Interfaces và kích hoạt Camera như hình bên dưới:
38 Hình 32: Cửa sổ Raspberry Pi Configuration
Cách 2: Kích hoạt từ giao diện Terminal bằng dòng lệnh:
Sudo raspi-config
Khi đó giao diện Raspberry Pi Software Configuration Tool được hiển thị. Nhấp chọn Interfacing Options:
Hình 33: Giao diện Raspberry Pi Software Configuration Tool Sau đó kích hoạt Camera và khởi động lại Pi:
39 Hình 34: kích hoạt Camera Pi
40
CHƯƠNG 4: CHƯƠNG TRÌNH PHÁT HIỆN NGỦ GẬT VÀ NGÁP NGỦ
4.1 Lưu đồ giải thuật
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”.
4.2 Lựa chọn bộ nhận diện khuôn mặt của OpenCV
Có rất nhiều model cascade đã huấn luyện sẵn do cộng đồng OpenCV thực hiện. Các model này chứa đặc trưng của đối tượng cần tìm trong ảnh tổng hợp vào file *.xml. Dựa vào model này mà ta có thể biết đối tượng cần tìm có trong ảnh không. Trong lib opencv cũng đã có sẵn 1 số model cascade dùng để nhận diện khuôn mặt.
Độ chính xác của việc phát hiện khuôn mặt phụ thuộc rất nhiều vào file cascade. Những file cascade được cung cấp sẵn theo lib OpenCV và các file cascade này có tỷ lệ nhận diện khác nhau.
Bây giờ chúng ta sẽ kiểm tra các file cascade này với 100 bức ảnh (trong đó chỉ có 80 bức ảnh là chứa khuôn mặt người thật). Chúng ta sẽ kiểm tra bằng phần mềm
47 Hình 42: Giao diện phần mềm Cascade Trainer Gui
Sau khi cài đặt xong phần mềm và khởi động, ta nhấp chọn Test.
Tiếp theo ta lựa chọn file cascade cần test, sau đó ta tinh chỉnh thông số để test (có thể giữ nguyên thông số).
Bước tiếp theo ta chọn file ảnh cần test và lựa chọn file lưu kết quả như hình bên dưới.
48 Sau khi kiểm tra xong chúng ta sẽ có một file như hình bên dưới.
Hình 44: Kết quả sau khi kiểm tra Kết quả sau khi kiểm tra các file cascade như sau:
- Haarcascade_frontalface_alt.xml: 75 khuôn mặt/80 khuôn mặt và nhận diện sai 2 ảnh.
- Haarcascade_frontalface_alt2.xml: 74 khuôn mặt/80 khuôn mặt nhận diện sai 4 hình ảnh.
- Haarcascade_frontalface_alt_tree.xml: 23 khuôn mặt/80 khuôn mặt.
- Haarcascade_frontalface_default.xml: 74 khuôn mặt/80 khuôn mặt và nhận diện sai 11 hình ảnh.
Như vậy, ta có thể dùng Haarcascade_frontalface_alt.xml hoặc Haarcascade_frontalface_alt2.xml để có kết quả tốt nhất.
49
CHƯƠNG 5: KẾT QUẢ, NHẬN XÉT VÀ ĐÁNH GIÁ
5.1 Kết quả
Bên dưới là hình ảnh của hệ thống phát hiện ngủ gật và ngáp ngủ. Khi lắp đặt lên xe ta chỉ cần kit Raspberry Pi và Camera Pi (màn hình, bàn phím và chuột chỉ cần thiết khi lập trình). Loa báo ta có thể sử dụng loa mini hoặc tận dụng hệ thống loa có sẵn trên xe. Còn về nguồn điện thì ta có thể sử dụng nguồn điện 12V trên xe ô tô (đủ để cung cấp cho Raspberry Pi và Camera Pi hoạt động bình thường).
Hình 45: Hệ thống phát hiện ngủ gật và ngáp ngủ
Dưới đây là một số hình ảnh cho thấy kết quả mà chương trình đã đạt được. Đánh dấu đúng vị trí mắt và miệng ở nhiều góc độ khác nhau.
50 Hình 46: Đánh dấu đúng vị trí mắt và miệng ở nhiều góc độ khác nhau.
51 Phát hiện ngủ gật trong điều kiện đủ sáng không có đeo kính.
Hình 47: Phát hiện ngủ gật trong điều kiện đủ sáng không có đeo kính Phát hiện ngủ gật trong điều kiện đủ sáng có đeo kính.
52 Phát hiện ngủ gật trong điều kiện thiếu sáng không có đeo kính.