【机器学习实战入门】使用OpenCV和Keras的驾驶员疲劳检测系统
嗜睡驾驶者警报系统
防止司机疲劳驾驶警报系统
中级 Python 项目 - 司机疲劳检测系统
疲劳检测是一种安全技术,能够预防因司机在驾驶过程中入睡而造成的事故。
本中级 Python 项目的目标是建立一个疲劳检测系统,该系统将检测到一个人的眼睛闭合了一段时间。当检测到疲劳时,该系统会向司机发出警报。
司机疲劳检测系统
在这个 Python 项目中,我们将使用 OpenCV 从网络摄像头获取图像,并将其输入到一个深度学习模型中,该模型将分类人的眼睛是“睁着”还是“闭着”。我们为这个 Python 项目采用的方法如下:
步骤 1 - 从相机接收图像作为输入。
步骤 2 - 检测图像中的人脸,并创建一个感兴趣区域 (ROI)。
步骤 3 - 从 ROI 中检测眼睛,并将其输入到分类器中。
步骤 4 - 分类器将对眼睛的状态进行分类,确定是睁着还是闭着。
步骤 5 - 计算得分以检查该人是否疲劳。
司机疲劳检测数据集
用于构建这个模型的数据集是我们自行创建的。为了构建数据集,我们编写了一个脚本,该脚本从相机捕获眼睛图像并存储在本地磁盘上。我们将这些图像按照“睁着”和“闭着”两个标签进行了分类。数据经过了手动清理,移除了对构建模型不必要的图片。数据集包括在不同光照条件下大约 7000 张人眼图像。在用我们的数据集训练模型后,我们附上了模型权重和模型架构文件“models/cnnCat2.h5”。
现在,您可以使用这个模型来分类一个人的眼睛是睁着还是闭着的。
另外,如果您想构建和训练您自己的模型,您可以下载数据集:如果您想要构建和训练自己的模型,可以下载数据集:链接: 驾驶员嗜睡检测数据集
数据介绍:
Driver Drowsiness Data
The dataset consists of 2900 images which include both normal and yawning images. Dataset is divided into training and testing, which is used in the project for training and testing respectively.
It is an excellent dataset for people who want to learn machine learning techniques for driver drowsiness detection.
Sample Data:
模型架构
我们使用的模型是基于 Keras 构建的卷积神经网络 (CNN)。卷积神经网络是一种专门用于图像分类的深度神经网络,其表现极其出色。CNN 通常包括一个输入层、一个输出层和一个可能包含多个隐藏层的结构。卷积操作使用一个滤波器在各层上进行 2D 矩阵乘法。
CNN 模型架构包含以下层:
- 卷积层;32 个节点,内核大小为 3
- 卷积层;32 个节点,内核大小为 3
- 卷积层;64 个节点,内核大小为 3
- 全连接层;128 个节点
- 最终层也是一个全连接层,包含 2 个节点。除了输出层使用了 Softmax 激活函数外,所有的层都使用了 ReLU 激活函数。
项目先决条件
本 Python 项目需要一个网络摄像头来捕获图像。您需要在系统上安装 Python(推荐版本 3.6),然后使用 pip 安装必要的包。
- OpenCV - pip install opencv-python(用于脸部和眼睛检测)
- TensorFlow - pip install tensorflow(Keras 使用 TensorFlow 作为后端)
- Keras - pip install keras(用于构建分类模型)
- Pygame - pip install pygame(用于播放警报声)
执行司机疲劳检测的步骤
从提供的 zip 文件中下载司机疲劳检测系统的项目源代码,并将文件解压到您的系统中:: 司机疲劳检测项目代码链接
zip 文件的内容:
项目文件结构 - 中级 Python 项目
“Haar 级联文件”文件夹包含用于从图像中检测对象的 xml 文件。我们的情况下,用于检测人的脸部和眼睛。
models 文件夹包含我们的模型文件“cnnCat2.h5”,该文件是在卷积神经网络上训练的。
我们有一个音频文件“alarm.wav”,在检测到人感到疲劳时会播放。
“Model.py”文件包含了我们通过训练数据集构建分类模型的程序。您可以在这个文件中看到卷积神经网络的实现。
“Drowsiness_detection.py”是我们项目的主要文件。要开始检测过程,我们需要运行这个文件。
现在我们来逐步了解算法的工作原理。
步骤 1 - 从相机接收图像作为输入
使用网络摄像头,我们将接收图像作为输入。为了访问摄像头,我们创建了一个无限循环,该循环将捕获每一帧。我们使用 OpenCV 提供的方法 cv2.VideoCapture(0) 来访问摄像头并设置捕获对象 (cap)。cap.read() 会读取每一帧,并将其存储在 frame 变量中。
步骤 2 - 检测图像中的人脸并创建感兴趣区域 (ROI)
为了在图像中检测人脸,我们首先需要将图像转换为灰度图,因为 OpenCV 的对象检测算法接受灰度图像作为输入。检测对象时我们不需要颜色信息。我们将使用 Haar 级联分类器来检测人脸。这行代码用于设置我们的分类器:face = cv2.CascadeClassifier(‘路径到我们的 Haar 级联 xml 文件’)。然后我们使用 faces = face.detectMultiScale(gray) 来完成检测任务。它返回一个检测结果数组,包含检测对象的 x 和 y 坐标,以及边界框的高度和宽度。我们现在可以遍历所有检测到的人脸,并为每个人脸绘制边界框。
for (x,y,w,h) in faces:
cv2.rectangle(frame, (x,y), (x+w, y+h), (100,100,100), 1 )
步骤 3 - 从 ROI 中检测眼睛并将其输入到分类器中
使用与检测人脸相同的程序来检测眼睛。首先,我们分别在 leye 和 reye 中设置眼睛的级联分类器,然后用 left_eye = leye.detectMultiScale(gray) 来检测左眼。接下来,我们需要从完整的图像中仅提取眼睛数据。通过提取眼睛的边界框,然后使用以下代码从帧中单独拉出眼睛图像,可以实现这一点。
l_eye = frame[ y : y+h, x : x+w ]
l_eye 仅包含眼睛的图像数据。这个数据将被输入到我们的 CNN 分类器中,该分类器将预测眼睛是睁着还是闭着。同样地,我们将利用 r_eye 提取右眼。
步骤 4 - 分类器将对眼睛是睁着还是闭着进行分类
我们使用 CNN 分类器来预测眼睛状态。为了将图像输入模型,需要执行某些操作,因为模型需要正确的维度才能开始工作。首先,我们使用 r_eye = cv2.cvtColor(r_eye, cv2.COLOR_BGR2GRAY) 将彩色图像转换为灰度图。然后,我们将图像大小调整为 2424 像素,因为我们的模型是在 2424 像素的图像上训练的,cv2.resize(r_eye, (24,24))。为了更好的收敛,我们对数据进行归一化处理 r_eye = r_eye/255(所有值都在 0-1 之间)。扩展维度以输入到分类器中。我们使用 model = load_model(‘models/cnnCat2.h5’) 加载我们的模型。现在使用模型预测每个眼睛的状态
lpred = model.predict_classes(l_eye)
如果 lpred[0] 的值为 1,说明眼睛是睁着的;如果 lpred[0] 的值为 0,则说明眼睛是闭着的。
步骤 5 - 计算得分以检查该人是否疲劳
得分基本上是用于判断一个人闭眼时间的一个值。如果两个眼睛都闭着,我们将不断增加得分;眼睛睁开时,我们则减少得分。使用 cv2.putText() 函数在屏幕上绘制结果,这将显示人的实时状态。
cv2.putText(frame, “Open”, (10, height-20), font, 1, (255,255,255), 1, cv2.LINE_AA )
例如,如果得分大于 15,这意味着人的眼睛闭合了一段时间。此时,我们将使用 sound.play() 发出警报声。
主文件的源代码如下所示:
import cv2
import os
from keras.models import load_model
import numpy as np
from pygame import mixer
import time
mixer.init()
sound = mixer.Sound('alarm.wav')
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')
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))
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 )
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
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
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):
# 该人感到困倦,我们发出警报声
cv2.imwrite(os.path.join(path,'image.jpg'),frame)
try:
sound.play()
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()
司机疲劳检测系统执行
现在让我们执行司机疲劳检测系统,并看看我们 ML 项目的工作情况。要开始项目,您需要打开命令提示符,进入“drowsiness detection.py”主要文件所在的目录。使用以下命令运行脚本。
python “drowsiness detection.py”
打开摄像头和开始检测可能需要几秒钟的时间。
示例截图:
-
运行疲劳检测程序 - 带有源代码的 Python 项目
-
训练新手的闭眼检测 Python 项目
-
初学者 Python 开源项目的睁眼检测
-
带有警报的 Python 开源项目
总结
在这个 Python 项目中,我们构建了一个可以以多种方式实施的疲劳驾驶警报系统。我们使用 OpenCV 通过 Haar 级联分类器检测人脸和眼睛,然后使用 CNN 模型预测状态。
参考资料
- Haar 级联分类器介绍
- 卷积神经网络基础
- 如何使用 OpenCV 进行面部检测
- Python 用于图像处理的教程
- 使用 Keras 构建深度学习模型的指南
- 理解 Softmax 激活函数
- Pygame 的简介与使用
- 实时视频处理中的 OpenCV 用法
- 在汽车中实现疲劳检测的技术探讨
- 机器学习在疲劳检测中的应用研究
- 用于检测驾驶员疲劳的深度学习模型详解
参考链接:https://data-flair.training/blogs/python-project-driver-drowsiness-detection-system/