You are on page 1of 11

Thực tập xử lý ảnh

Hệ thống cảnh báo ngủ gật khi lái xe ôtô


Chương 1. CƠ SỞ LÝ THUYẾT

1. Hệ thống cảnh báo lái xe buồn ngủ


Phát hiện buồn ngủ là một công nghệ an toàn có thể ngăn ngừa các tai nạn do người lái xe ngủ
gật trong khi lái xe.Mục tiêu trong bài báo cáo này của nhóm em là dùng ngôn ngữ Python
làm trung gian xây dựng một hệ thống phát hiện buồn ngủ sẽ phát hiện ra mắt của một người
đang nhắm lại trong vài giây.Hệ thống này sẽ cảnh báo người lái khi phát hiện buồn ngủ.
Trong đề tài này, chúng em sẽ sử dụng OpenCV để thu thập hình ảnh từ webcam và đưa
chúng vào mô hình Học sâu sẽ phân loại xem mắt của người đó là 'Mở' hay 'Đóng'. Cách tiếp
cận chúng em sẽ sử dụng cho đề tài này gồm 5 bước như sau:
Bước 1 - Lấy hình ảnh làm đầu vào từ máy ảnh.
Bước 2 - Phát hiện khuôn mặt trong ảnh và tạo Vùng yêu thích (ROI).
Bước 3 - Phát hiện các mắt từ ROI và đưa nó vào bộ phân loại.
Bước 4 - Bộ phân loại sẽ phân loại xem mắt đang mở hay đang nhắm.
Bước 5 - Tính điểm để kiểm tra xem người đó có buồn ngủ hay không.
2. Bộ dữ liệu phát hiện buồn ngủ của người lái xe
Tập dữ liệu được sử dụng cho mô hình này do chúng em lấy từ nguồn trên mạng. Để tạo tập
dữ liệu, chúng ta đã viết một tập lệnh thu hút ánh nhìn từ máy ảnh và lưu trữ trong ổ đĩa.
Chúng sẽ đã tách thành các nhãn tương ứng 'Mở' hoặc 'Đã đóng'. Dữ liệu được làm sạch thủ
công bằng cách loại bỏ các hình ảnh không mong muốn không cần thiết để xây dựng mô
hình.Dữ liệu bao gồm khoảng 7000 hình ảnh về mắt của mọi người trong các điều kiện ánh
sáng khác nhau.Sau khi huấn luyện mô hình trên tập dữ liệu đã có, chúng sẽ được đánh kèm
các trọng số cuối cùng. Chúng em sử dụng mô hình này để phân loại xem mắt của một người
đang mở hay đang nhắm lại.
3. Kiến trúc mô hình
Mô hình mà chúng em đã sử dụng được xây dựng với Keras bằng cách sử dụng Mạng nơ-ron
(CNN).Mạng nơ-ron tích tụ là một loại mạng nơ-ron sâu đặc biệt hoạt động rất tốt cho mục
đích phân loại hình ảnh.CNN về cơ bản bao gồm một lớp đầu vào, một lớp đầu ra và một lớp
ẩn có thể có nhiều lớp.Phép toán tích chập được thực hiện trên các lớp này bằng cách sử dụng
bộ lọc thực hiện phép nhân ma trận 2D trên lớp và bộ lọc.
Kiến trúc mô hình CNN bao gồm các lớp sau:
Lớp chuyển đổi; 32 nút, kích thước hạt nhân 3
Lớp chuyển đổi; 32 nút, kích thước hạt nhân 3

1
Thực tập xử lý ảnh
Lớp chuyển đổi; 64 nút, kích thước hạt nhân 3
Lớp kết nối đầy đủ; 128 nút
Lớp cuối cùng cũng là lớp được kết nối đầy đủ với 2 nút.Chức năng kích hoạt Relu được sử
dụng trong tất cả các lớp ngoại trừ lớp đầu ra mà chúng ta đã sử dụng Softmax.
4. Điều kiện thực hiện đề tài
Yêu cầu đối với đề tài Python này là cần có một webcam mà qua đó chúng ta sẽ chụp ảnh.
Chúng ta cần cài đặt Python (phiên bản 3.6 được khuyến nghị) trên hệ thống của mình, sau đó
sử dụng pip, chúng ta có thể cài đặt các gói cần thiết sau để thực hiện .
OpenCV - pip cài đặt opencv-python (nhận diện khuôn mặt và mắt).
TensorFlow - pip cài đặt tensorflow (keras sử dụng TensorFlow làm phụ trợ).
Keras - pip cài đặt keras (để xây dựng mô hình phân loại của chúng tôi).
Pygame - pip cài đặt pygame (để phát âm thanh báo động).

2
Thực tập xử lý ảnh

Chương 2. NỘI DUNG

1. Lưu đồ giải thuật

BẮT Đầu
ĐẦU

Lấy hình ảnh từ đầu vào của máy


ảnh

Phát hiện vùng khuôn măt và tạo


vùng hình ảnh quan tâm

Phát hiện các mắt từ ROI và đưa nó


vào bộ phân loại

Bộ phân loại sẽ phân loại xem mắt


đang mở hay nhắm

Tính điểm để kiểm tra xem một


người có buồn ngủ hay không

KẾT
THÚC

Giải thích lưu đồ


Lấy hình ảnh làm đầu vào từ máy ảnh
Với một webcam, chúng ta sẽ lấy hình ảnh làm đầu vào. Vì vậy, để truy cập webcam, chúng
ta đã tạo một vòng lặp vô hạn sẽ chụp từng khung hình. Chúng ta sử dụng phương pháp được
cung cấp bởi OpenCV, cv2.VideoCapture (0) để truy cập máy ảnh và đặt đối tượng chụp ,
cap.read () sẽ đọc từng khung và chúng ta lưu hình ảnh trong một biến khung.
Phát hiện khuôn mặt trong ảnh và tạo vùng quan tâm (ROI)
Để phát hiện khuôn mặt trong hình ảnh, trước tiên chúng ta cần chuyển hình ảnh thành thang
độ xám vì thuật toán OpenCV để phát hiện đối tượng lấy hình ảnh màu xám trong đầu vào.
Chúng ta không cần thông tin về màu sắc để phát hiện các đối tượng. Chúng ta sẽ sử dụng bộ
phân loại tầng haar để phát hiện khuôn mặt.Dòng này được sử dụng để đặt bộ phân loại: face
= cv2.CascadeClassifier.Sau đó, thực hiện phát hiện bằng cách sử dụng face =
face.detectMultiScale (màu xám). Nó trả về một mảng các phát hiện với tọa độ x, y và chiều

3
Thực tập xử lý ảnh
cao, chiều rộng của hộp ranh giới của đối tượng. Bây giờ chúng ta có thể lặp lại các mặt và vẽ
các hộp ranh giới cho mỗi mặt.
Phát hiện các mắt từ ROI và đưa nó vào bộ phân loại
Quy trình tương tự để phát hiện khuôn mặt được sử dụng để phát hiện mắt. Đầu tiên, chúng ta
đặt bộ phân loại tầng cho các mắt lần lượt là leye và reye , sau đó phát hiện các mắt bằng cách
sử dụng left_eye = leye.detectMultiScale (xám).Bây giờ chúng ta chỉ cần trích xuất dữ liệu
đôi mắt từ hình ảnh đầy đủ. Điều này có thể đạt được bằng cách trích xuất hộp ranh giới của
mắt và sau đó chúng ta có thể lấy hình ảnh mắt ra khỏi khung bằng mã này.
l_eye = frame [ y : y + h, x : x + w ]
l_eye chỉ chứa dữ liệu hình ảnh của mắt. Điều này sẽ được đưa vào bộ phân loại CNN của
chúng tôi, công cụ này sẽ dự đoán xem mắt đang mở hay nhắm lại. Tương tự, chúng ta sẽ
trích xuất mắt phải thành r_eye .
Bộ phân loại sẽ phân loại xem mắt đang mở hay nhắm
Chúng ta đang sử dụng công cụ phân loại CNN để dự đoán tình trạng mắt. Để đưa hình ảnh
của chúng vào mô hình, chúng ta cần thực hiện một số thao tác nhất định vì mô hình cần có
kích thước chính xác để bắt đầu. Đầu tiên, chúng ta chuyển đổi hình ảnh màu thành thang độ
xám bằng cách sử dụng r_eye = cv2.cvtColor (r_eye, cv2.COLOR_BGR2GRAY) . Sau đó,
chúng ta thay đổi kích thước hình ảnh thành 24 * 24 pixel vì mô hình của chúng ta đã được
đào tạo về hình ảnh 24 * 24 pixel cv2.resize (r_eye, (24,24)) . Chúng ta chuẩn hóa dữ liệu của
mình để hội tụ tốt hơn r_eye = r_eye / 255 (Tất cả các giá trị sẽ nằm trong khoảng 0-1). Mở
rộng các thứ nguyên để đưa vào trình phân loại. Chúng ta đã tải mô hình của mình bằng cách
sử dụng model = load_model ('models / cnnCat2.h5') . Bây giờ chúng ta dự đoán từng mắt với
mô hình lpred = model.posystem_classes (l_eye) của chúng. Nếu giá trị của lpred [0] = 1, nó
cho biết rằng mắt đang mở, nếu giá trị của lpred [0] = 0 thì nó cho biết rằng mắt đang nhắm.
Tính điểm để kiểm tra xem một người có buồn ngủ hay không
Về cơ bản, điểm số là một giá trị mà chúng ta sẽ sử dụng để xác định xem người đó đã nhắm
mắt trong bao lâu. Vì vậy, nếu nhắm cả hai mắt, chúng ta sẽ tiếp tục tăng điểm và khi mở mắt,
chúng ta sẽ giảm điểm. Chúng ta đang vẽ kết quả trên màn hình bằng cách sử dụng hàm
cv2.putText () sẽ hiển thị trạng thái thời gian thực của người đó.
cv2. putText ( frame, “Open”, ( 10 , height- 20 ) , font, 1 , ( 255 , 255 , 255 ) , 1 , cv2.
LINE_AA )
Một ngưỡng được xác định, chẳng hạn nếu điểm lớn hơn 15, nghĩa là người đó nhắm mắt
trong một khoảng thời gian dài. Đây là lúc chúng ta phát ra tiếng bíp báo thức bằng
sound.play ().

4
Thực tập xử lý ảnh

2. Chương trình nhận dạng

#Hệ thống phát hiện buồn ngủ cho người lái xe


#OpenCV (nhận diện khuôn mặt và mắt).
#TensorFlow (keras sử dụng TensorFlow làm phụ trợ).
#Keras (để xây dựng mô hình phân loại ).
#Pygame (để phát âm thanh báo động).

import cv2
import os
from tensorflow.keras.models import load_model
import numpy as np
from pygame import mixer
import time
mixer.init()
sound = mixer.Sound('sky.wav')

#Phát hiện khuôn mặt trong ảnh và tạo vùng quan tâm (ROI)
#để phát hiện đối tượng lấy hình ảnh màu xám đầu vào.
# ta sẽ sử dụng bộ phân loại tầng hear để phát hiện khuôn mặt.
# Dòng này được sử dụng để đặt bộ phân loại face = cv2.CascadeClassifier
# ('đường dẫn đến tệp xml tầng haar ') .
# Sau đó thực hiện phát hiện bằng cách sử dụng face = face.detectMultiScale (màu xám) .
# Nó trả về một mảng các phát hiện với tọa độ x, y và chiều cao, chiều rộng của hộp ranh giới
của đối tượng.
# Bây giờ chúng ta có thể lặp lại các mặt và vẽ các hộp ranh giới cho mỗi mặt.

face = cv2.CascadeClassifier('haar cascade files\haarcascade_frontalface_alt.xml')


leye = cv2.CascadeClassifier('haar cascade files\haarcascade_lefteye_2splits.xml')
reye = cv2.CascadeClassifier('haar cascade files\haarcascade_righteye_2splits.xml')

5
Thực tập xử lý ảnh

#1__ Lấy hình ảnh làm đầu vào từ máy ảnh


#Với webcam, ta sẽ lấy hình ảnh làm đầu vào.
# Vì vậy, để truy cập webcam, em đã tạo một vòng lặp vô hạn sẽ chụp từng khung hình.
# sử dụng phương pháp được cung cấp bởi OpenCV, cv2.VideoCapture (0)

lbl=['Close','Open']
model = load_model('models/cnncat2.h5')
path = os.getcwd()
cap = cv2.VideoCapture(0)
font = cv2.FONT_HERSHEY_COMPLEX_SMALL
count=0
score=0
thicc=2
rpred=[99]
lpred=[99]
while(True):
ret, frame = cap.read()
height,width = frame.shape[:2]
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces =
face.detectMultiScale(gray,minNeighbors=5,scaleFactor=1.1,minSize=(25,25))

#3Phát hiện các mắt từ ROI và đưa nó vào bộ phân loại :


#Quy trình tương tự để phát hiện khuôn mặt được sử dụng để phát hiện mắt.
# Đầu tiên, đặt bộ phân loại tầng cho các mắt lần lượt là leye và reye ,
# sau đó phát hiện các mắt bằng cách sử dụng left_eye = leye.detectMultiScale (xám) .
# Bây giờ chúng ta chỉ cần trích xuất dữ liệu đôi mắt từ hình ảnh đầy đủ.
# Điều này có thể đạt được bằng cách trích xuất hộp của mắt và sau đó chúng ta có thể lấy
hình ảnh mắt ra khỏi
# khung bằng mã này.

6
Thực tập xử lý ảnh
left_eye = leye.detectMultiScale(gray)
right_eye = reye.detectMultiScale(gray)

cv2.rectangle(frame, (0,height-50) , (200,height) , (0,0,0) , thickness=cv2.FILLED )


for (x,y,w,h) in faces:
cv2.rectangle(frame, (x,y) , (x+w,y+h) , (100,100,100) , 1 )

#4Bộ phân loại sẽ phân loại xem mắt đang mở hay nhắm
#em đang sử dụng công cụ phân loại CNN để dự đoán tình trạng mắt.
# Để đưa hình ảnh của em vào mô hình, cần thực hiện một số thao tác nhất định
# vì mô hình cần có kích thước chính xác để bắt đầu. Đầu tiên, em chuyển đổi hình ảnh màu
thành
# thang độ xám bằng cách sử dụng r_eye = cv2.cvtColor (r_eye, cv2.COLOR_BGR2GRAY) .
# Sau đó, em thay đổi kích thước hình ảnh thành 24 * 24 pixel

for (x,y,w,h) in right_eye:


r_eye=frame[y:y+h,x:x+w]
count=count+1
r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY)
r_eye = cv2.resize(r_eye,(24,24))
r_eye= r_eye/255
r_eye= r_eye.reshape(24,24,-1)
r_eye = np.expand_dims(r_eye,axis=0)
rpred = model.predict_classes(r_eye)
if(rpred[0]==1):
lbl='Open'
if(rpred[0]==0):
lbl='Closed'
break
for (x,y,w,h) in left_eye:
l_eye=frame[y:y+h,x:x+w]
count=count+1

7
Thực tập xử lý ảnh
l_eye = cv2.cvtColor(l_eye,cv2.COLOR_BGR2GRAY)
l_eye = cv2.resize(l_eye,(24,24))
l_eye= l_eye/255
l_eye=l_eye.reshape(24,24,-1)
l_eye = np.expand_dims(l_eye,axis=0)
lpred = model.predict_classes(l_eye)
if(lpred[0]==1):
lbl='Open'
if(lpred[0]==0):
lbl='Closed'
break

#5__Tính điểm để kiểm tra xem một người có buồn ngủ hay không
# (Về cơ bản, điểm số là một giá trị mà mình sẽ sử dụng để xác định xem người đó đã nhắm
mắt trong bao lâu.
# Vì vậy, nếu nhắm cả hai mắt, chúng ta sẽ tiếp tục tăng điểm và khi mở mắt,
# giảm điểm. em đang vẽ kết quả trên màn hình bằng cách sử dụng hàm
# cv2.putText () sẽ hiển thị trạng thái thời gian thực của người đó)

if(rpred[0]==0 and lpred[0]==0):


score=score+1
cv2.putText(frame,"Closed",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)

# if(rpred[0]==1 or lpred[0]==1):
else:
score=score-1
cv2.putText(frame,"Open",(10,height-20), font, 1,(255,255,255),1,cv2.LINE_AA)
if (score < 0):
score = 0
cv2.putText(frame, 'Score:' + str(score), (100, height - 20), font, 1, (255, 255, 255), 1,
cv2.LINE_AA)
if (score > 15):

8
Thực tập xử lý ảnh
# person is feeling sleepy so we beep the alarm

cv2.imwrite(os.path.join(path, 'image.jpg'), frame)


try:
sound.play()
time.time_ns(100)
except: # isplaying = False
pass
if (thicc < 16):
thicc = thicc + 2
else:
thicc = thicc - 2
if (thicc < 2):
thicc = 2
cv2.rectangle(frame, (0, 0), (width, height), (0, 0, 255), thicc)
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()

9
Thực tập xử lý ảnh

Chương 3. KẾT QUẢ

10
Thực tập xử lý ảnh

TÀI LIỆU THAM KHẢO

 Nguyễn mạnh hùng “Mạng nơ-ron (CNN).”


http://lib.uet.vnu.edu.vn/bitstream/123456789/1052/1/Lu%E1%BA%ADn%20v%C4%83n
%20-%20Nguy%E1%BB%85n%20M%E1%BA%A1nh%20H%C3%B9ng.pdf
 Trần hoài linh “ mạng nơ ron (CNN) và ứng dụng trong xử lý ảnh
 Opencv
“http://docs.opencv.org/ https://techmaster.vn/ https://pythonprogramming.net/”

11

You might also like