睡意检测是一项安全技术,可以防止驾驶员在驾驶时入睡而导致的事故。
这个中间Python项目的目的是建立一个睡意检测系统,该系统将检测人的眼睛闭合几秒钟。 当检测到困倦时,该系统将警告驾驶员。
在此Python项目中,我们将使用OpenCV收集来自网络摄像头的图像,并将其输入到深度学习模型中,该模型将对人的眼睛是“睁开”还是“闭合”进行分类。 我们将用于此Python项目的方法如下:
步骤1 –将图像作为来自摄像机的输入。
第2步–检测图像中的人脸并创建关注区域(ROI)。
第3步–从ROI中检测眼睛并将其输入分类器。
步骤4 –分类器将对睁开或闭合的眼睛进行分类。
步骤5 –计算分数以检查该人是否困倦。
现在,在开始 先决条件,数据集和模型体系结构之前 ,如果您是新手,我建议您参考此 Python Master工作表 以学习Python编程语言的所有必要概念。
此Python项目的要求是一个网络摄像头,我们将通过该摄像头捕获图像。 您需要在系统上安装Python(建议使用3.6版),然后使用pip安装必需的软件包。
用于此模型的数据集由我们创建。 为了创建数据集,我们
编写了一个脚本,可以捕获相机的眼睛并将其存储在本地
磁盘。 我们将它们分为各自的标签“打开”或
'关闭'。 通过删除不需要的图像手动清除了数据
这对于构建模型不是必需的。 数据包括
在不同的照明条件下,大约可以看到7000张人眼的图像。
在我们的数据集上训练模型后,我们将最终
权重和模型架构文件“ models / cnnCat2.h5”。
现在,您可以使用此模型对人眼睁开或闭眼进行分类。
我们使用的模型是通过Keras使用卷积神经网络(CNN)构建的。 卷积神经网络是一种特殊的深度神经网络,在图像分类方面表现非常出色。 CNN基本上由一个输入层,一个输出层和一个可以包含多个层的隐藏层组成。 使用在层和滤波器上执行2D矩阵乘法的滤波器对这些层执行卷积运算。
CNN模型架构包括以下几层:
最后一层也是具有2个节点的完全连接的层。 在所有
层,除了在输出层中使用Relu激活功能
我们使用Softmax。
从zip下载Python项目源代码,然后将文件提取到系统中: Python Project Zip File
压缩文件的内容为:
现在,让我们逐步了解我们的算法。
使用网络摄像头,我们将图像作为输入。 因此,要访问网络摄像头,我们进行了无限循环,将捕获每个帧。 我们使用OpenCV提供的方法cv2.VideoCapture(0)访问摄像机并设置捕获对象(上限)。 cap.read()将读取每一帧,然后将图像存储在frame变量中。
要检测图像中的人脸,我们首先需要将图像转换为灰度,因为用于对象检测的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 )
检测脸部的相同过程也用于检测眼睛。 首先,我们为leye和reye中的眼睛分别设置级联分类器,然后使用left_eye = leye.detectMultiScale(gray)来检测眼睛。 现在,我们只需要从完整图像中提取眼睛数据即可。 这可以通过提取眼睛的边界框来实现,然后我们可以使用此代码从帧中提取眼睛图像。
l_eye = frame[ y : y+h, x : x+w ]
l_eye仅包含眼睛的图像数据。 这将被输入到我们的CNN分类器中,该分类器将预测眼睛是睁着还是闭着。 同样,我们将右眼提取到r_eye中 。
我们正在使用CNN分类器来预测眼睛状态。 要将图像输入到模型中,我们需要执行某些操作,因为模型首先需要正确的尺寸。 首先,我们使用r_eye = cv2.cvtColor(r_eye,cv2.COLOR_BGR2GRAY)将彩色图像转换为灰度。
然后,当我们的模型在24 * 24像素图像cv2.resize(r_eye,(24,24))上训练时,我们将图像调整为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,则表明眼睛是张开的。
分数基本上是一个值,我们将使用该值来确定该人闭上眼睛多长时间。 因此,如果两只眼睛都闭合,我们将继续增加得分,而当眼睛睁开时,我们将降低得分。 我们正在使用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):
#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()
让我们开始我们的项目,看看我们项目的工作。 要启动该项目,您需要打开命令提示符,转到主文件“ drowsiness detection.py”所在的目录。 使用此命令运行脚本。
python “drowsiness detection.py”
打开网络摄像头并开始检测可能需要几秒钟。
屏幕截图示例:
输出截图:
1.闭眼检测
2.睁开眼睛检测
3.睡眠警报
在这个Python项目中,我们构建了一个昏昏欲睡的驾驶员警报系统,您可以通过多种方式实施该系统。 我们使用Haar级联分类器使用OpenCV检测面部和眼睛,然后使用CNN模型预测状态。
如果您喜欢嗜睡检测系统中级Python项目,请在社交媒体上与您的朋友和同事共享。 有关更有趣的Python项目,请参考- 14个带有源代码的酷Python项目!!
翻译自: https://hackernoon.com/driver-drowsiness-detection-system-a-python-project-with-source-code-hc223yeh