困倦检测报警项目
困倦检测系统
在此 Python 项目中,我们将使用 OpenCV 从网络摄像头收集图像并将其输入深度学习模型,该模型将分类人的眼睛是“睁开”还是“闭着”,来决定是否困倦,如果判断困倦则调用警铃进行报警行为。我们将在这个 Python 项目中使用的方法如下:
步骤 1 –将图像作为来自相机的输入。
步骤 2 –检测图像中的人脸并创建感兴趣区域 (ROI)。
步骤 3 –从 ROI 中检测眼睛并将其输入分类器。
第 4 步 –分类器将对眼睛是睁着还是闭着进行分类。
步骤 5 –计算分数以检查该人是否困倦。
项目效果的展示如下:
困倦检测数据集
该数据包含约 7000 张不同光照条件下人眼的图像。您可以使用此模型来对人的眼睛是睁着还是闭着进行分类。
下载数据集:https://www.kaggle.com/datasets/serenaraju/yawn-eye-dataset-new
模型架构
我们使用的模型是使用卷积神经网络 (CNN)通过 Keras 构建的。卷积神经网络是一种特殊类型的深度神经网络,在图像分类方面表现非常出色。
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 的内容是:
- “haar Cascade files”文件夹包含从图像中检测对象所需的 xml 文件。在我们的例子中,我们正在检测人的面部和眼睛。
- models 文件夹包含我们的模型文件“cnnCat2.h5”,该文件是在卷积神经网络上进行训练的。
- 我们有一个音频剪辑“alarm.wav”,当人们感到昏昏欲睡时会播放该音频剪辑。
- “Model.py”文件包含我们通过对数据集进行训练来构建分类模型的程序。您可以在该文件中看到卷积神经网络的实现。
- “睡意检测.py”是我们项目的主文件。要开始检测过程,我们必须运行该文件。
现在让我们逐步了解我们的算法是如何工作的。
步骤 1 – 将图像作为来自相机的输入
使用网络摄像头,我们将图像作为输入。因此,为了访问网络摄像头,我们制作了一个无限循环来捕获每一帧。我们使用OpenCV提供的方法cv2.VideoCapture(0)来访问相机并设置捕获对象(cap)。cap.read()将读取每一帧,并将图像存储在帧变量中。
第 2 步 – 检测图像中的人脸并创建感兴趣区域 (ROI)
为了检测图像中的人脸,我们需要首先将图像转换为灰度图像,因为用于对象检测的 OpenCV 算法在输入中采用灰度图像。我们不需要颜色信息来检测对象。我们将使用 haar 级联分类器来检测人脸。
face = cv2.CascadeClassifier('path to our haar Cascade xml file')。
然后我们使用 faces =face.detectMultiScale(gray) 执行检测。它返回一个检测数组,其中包含 x、y 坐标和高度(对象边界框的宽度)。现在我们可以迭代这些面并为每个面绘制边界框。
第 3 步 – 从 ROI 中检测眼睛并将其输入分类器
检测眼睛的过程与检测面部的过程相同。首先,我们分别为leye和reye中的眼睛设置级联分类器,然后使用left_eye = leye.detectMultiScale(gray)检测眼睛。现在我们只需要从完整图像中提取眼睛数据。这可以通过提取眼睛的边界框来实现,然后我们可以使用此代码从帧中提取眼睛图像。
l_eye仅包含眼睛的图像数据。这将被输入到我们的 CNN 分类器中,该分类器将预测眼睛是睁着还是闭着。同样,我们将把右眼提取到r_eye中。
步骤 4 – 分类器将对眼睛是睁着还是闭着进行分类
我们使用卷积模型分类器来预测眼睛状态。为了将图像输入模型,我们需要执行某些操作,因为模型需要正确的尺寸来开始。
首先,我们使用r_eye = cv2.cvtColor(r_eye, cv2.COLOR_BGR2GRAY)将彩色图像转换为灰度图像。
然后,我们将图像大小调整为 24*24 像素,因为我们的模型是在 24*24 像素图像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() 函数在屏幕上绘制结果,该函数将显示人员的实时状态。
完整的代码如下:
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 = np.argmax(model.predict(r_eye), axis=-1)
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 = np.argmax(model.predict(l_eye), axis=-1)
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):
#person is feeling sleepy so we beep the alarm
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()
执行困倦检测项目
让我们执行项目并查看我们的机器学习项目的工作情况。要启动项目,可以直接在IDE平台运行drowsiness detector.py,也可以打开命令提示符,进入主文件“drowsiness detector.py”所在的目录。使用此命令运行脚本。
python drowsiness detector.py
打开网络摄像头并开始检测可能需要几秒钟的时间。
截图示例:
项目代码链接:
作者
arwin.yu.98@gmail.com