1、本项目通过YOLOv5-5.0、Dlib和PySide2实现了一个疲劳驾驶检测系统,可为一些同学的课设、大作业等提供参考。该项目分为两个检测部分,疲劳检测和分心行为检测。 疲劳检测部分,使用Dlib进行人脸关键点检测,然后通过计算眼睛和嘴巴的开合程度来判断是存在否闭眼或者打哈欠,并使用Perclos模型计算疲劳程度。 分心行为检测部分,使用YOLOv5检测是否存在玩手机、抽烟、喝水这三种行为。最终检测效果如图所示。
2、本项目提供玩手机、抽烟、喝水这三种行为的xml格式目标检测数据集,共3547张图片,如图所示。可用于自己训练,可将YOLOv5替换为YOLOv7、YOLOv8等YOLO系列模型。
用pycharm打开项目后,在终端conda配置的虚拟环境或本地环境输入以下命令:
pip install torch==1.7.1+cu110 torchvision==0.8.2+cu110 torchaudio===0.7.2 -f https://download.pytorch.org/whl/torch_stable.html
YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。主要的改进思路如下:
1、输入端:在模型训练阶段,提出了一些改进思路,主要包括Mosaic数据增强、自适应锚框计算、自适应图片缩放;
2、基准网络:融合其它检测算法中的一些新思路,主要包括:Focus结构与CSP结构;
3、Neck网络:目标检测网络在BackBone与最后的Head输出层之间往往会插入一些层,YOLOv5中添加了FPN+PAN结构;
4、Head输出层:输出层的锚框机制与YOLOv4相同,主要改进的是训练时的损失函数GIOU_Loss,以及预测框筛选的DIOU_nms。
YOLOv5的模型整体结构如图所示,在本项目算法中, YOLOv5用于目标检测,即检测face、drink、phone、smoke四个目标类别。从而判断驾驶员是否存在玩手机、抽烟、喝水这三种行为,并将检测出来的驾驶员人脸进行框出。
使用YOLOv5对当前摄像头采集的实时画面进行推理后,可得到相关目标检测结果,包括画面中的目标框类别、目标的置信度、目标框的左上角和右下角坐标(以实时图像的左上角为坐标原点)。再使用一个for循环读取存放了目标类别的列表lab,并使用if-else语句对取出的目标类别进行判断,若目标为"phone"、“smoke”、"drink"中的一种,则分别在前端ui界面中用红色字体显示“正在用手机”、“正在抽烟”、“正在喝水”、“请不要分心”字符串。对存在分心行为的驾驶员进行警示提醒。判断代码如下所示:
# 如果检测到分心行为
# 将信息返回到前端ui,使用红色字体来体现
# 并加ActionCOUNTER减1,以延长循环时间
for i in lab:
if(i == "phone"):
window.label_6.setText("正在用手机")
window.label_9.setText("请不要分心")
if ActionCOUNTER > 0:
ActionCOUNTER -= 1
elif(i == "smoke"):
window.label_7.setText("正在抽烟")
window.label_9.setText("请不要分心")
if ActionCOUNTER > 0:
ActionCOUNTER -= 1
elif(i == "drink"):
window.label_8.setText("正在喝水")
window.label_9.setText("请不要分心")
if ActionCOUNTER > 0:
ActionCOUNTER -= 1
若检测到玩手机行为,则在界面的右边以红色字体提示“正在用手机”、“请不要分心”,对驾驶员起到警示提醒的作用。并在左侧的实时显示画面中对手机进行框出,同时显示手机目标的置信度。
同理,若在摄像头采集的实时画面中检测到抽烟的行为,则使用“smoke”对烟进行框出,并显示烟的目标置信度。同时在显示窗口的右侧以红色字体提示驾驶人员“正在抽烟”、“请不要分心”。
喝水行为的检测与抽烟、玩手机行为检测类似,可以看到,本文算法也能够对喝水行为进行有效检测。
Dlib是一个用C++开发的开源工具包,可以用于创建复杂的机器学习算法来解决实际问题,目前已被广泛的应用在工业和学术领域,包括机器人,嵌入式设备,移动电话和大型高性能计算环境。相对于tensorflow和PyTorch,它在图像处理以及人脸面部特征提取、分类及对比这几个方面具有较强的通用性和优越性。因此,Dlib正在越来越广泛地应用在人脸识别技术领域。这个库使用独立封装,在不借助第三方库的情况下,可以直接移植到自己的项目中进行使用。
在本算法中首先创建一个人脸检测器对象frontal_face_detector来检测图像中是否存在人脸,若存在人脸,则使用detector对象检测图像中的人脸,并返回人脸位置信息。然后再创建一个关键点检测器对象shape_predictor,并读取本项目中已训练好的模型文件。最后,对于每个人脸使用shape_predictor对象检测出其关键点,输出的shape对象即为检测到的关键点信息。对于闭眼疲劳检测而言,首先基于dlib人脸识别的68个特征点、分别获取左右眼面部标志的索引,通过opencv对视频流进行灰度化处理,检测出人眼的位置信息。然后计算眼睛长宽比 EAR,当人眼睁开时,EAR在某个值上下波动,当人眼闭合时,EAR迅速下降,理论上会接近于零。当前帧两双眼睛宽高比与前一帧的差值的绝对值(EAR)大于0.2,则认为是疲劳。对于打哈欠疲劳检测而言,只要产生打哈欠的动作即归类为“疲劳”。主要取人脸六个参考点来计算嘴巴的张开度,检测到嘴巴张开度超过一定阈值,则判为打哈欠疲劳。
本项目将眨眼、打哈欠的疲劳检测写到了myfatigue.py脚本里面,有详细注释,调用即可。在main.py中进行疲劳判断的核心代码如下:
# 疲劳判断
# 眨眼判断
if eye < EYE_AR_THRESH:
# 如果眼睛开合程度小于设定好的阈值
# 则两个和眼睛相关的计数器加1
COUNTER += 1
Rolleye += 1
else:
# 如果连续2次都小于阈值,则表示进行了一次眨眼活动
if COUNTER >= EYE_AR_CONSEC_FRAMES:
TOTAL += 1
window.label_3.setText("眨眼次数:" + str(TOTAL))
# 重置眼帧计数器
COUNTER = 0
# 哈欠判断,同上
if mouth > MAR_THRESH:
mCOUNTER += 1
Rollmouth += 1
else:
# 如果连续3次都小于阈值,则表示打了一次哈欠
if mCOUNTER >= MOUTH_AR_CONSEC_FRAMES:
mTOTAL += 1
window.label_4.setText("哈欠次数:" + str(mTOTAL))
# 重置嘴帧计数器
mCOUNTER = 0
将检测出的左右眼部、嘴部区域关键点使用椭圆形绿色线框进行绘制,并在界面右侧的第一行文本提醒区域“疲劳检测”使用红色字体提示“疲劳!!!”,从而对存在眨眼、打哈欠疲劳行为的驾驶人员进行提示警告。另外,在界面右侧的第二行文本中统计当前摄像头画面中驾驶人员的眨眼次数和打哈欠次数,并进行实时显示。
Perclos疲劳参数是指在单位时间内眼睛闭合程度超过某一阈值(70%、80%等)的时间占总时间的百分比。目前,Perclos方法有三种判断疲劳的不同准则,分别为EM准则、P70准则、P80准则。其具体含义如下:
EM准则:瞳孔被眼睑覆盖超50%的面积,则认为眼睛是闭合的;
P70准则:瞳孔被眼睑覆盖超70%的面积,则认为眼睛是闭合的;
P80准则:瞳孔被眼睑覆盖超过80%的面积,则认为眼睛是闭合的。
本项目考虑到,当人注意力特别集中或处在沉思状态时可能也会有眼睑覆盖瞳孔超过50%甚至70%的可能,所以采用的是P80准则。
本项目中疲劳判断以150帧作为一个周期,计算出的Perclos模型得分超过0.38时,判为疲劳状态。核心判断代码如下:
# 疲劳模型
# 以150帧为一个循环
# 每一帧Roll加1
Roll += 1
# 当检测满150帧时,计算模型得分
if Roll == 150:
# 计算Perclos模型得分
perclos = (Rolleye/Roll) + (Rollmouth/Roll)*0.2
# 在前端UI输出perclos值
Ui_MainWindow.printf(window,"过去150帧中,Perclos得分为"+str(round(perclos,3)))
# 当过去的150帧中,Perclos模型得分超过0.38时,判断为疲劳状态
if perclos > 0.38:
Ui_MainWindow.printf(window,"当前处于疲劳状态")
window.label_10.setText("疲劳!!!")
Ui_MainWindow.printf(window,"")
else:
Ui_MainWindow.printf(window,"当前处于清醒状态")
window.label_10.setText("清醒")
Ui_MainWindow.printf(window,"")
本项目在显示控件里设置了一个窗口,用于实时显示疲劳分数计算结果和判断结果。如图所示,当循环判断150帧中Perclos模型得分超过0.38时,判为疲劳状态,并显示字符串“当前处于疲劳状态”进行提醒。否则,输出字符串“当前处于清醒状态”。该阈值预设为0.38,可根据不同的需求进行手动调节,以使算法获得不同的疲劳判断灵敏度。
为有效监测驾驶员状态、避免交通事故的发生,本项目利用YOLOv5目标检测技术、人脸关键点检测分析技术结合的新方法,对驾驶员的分心、疲劳驾驶行为进行实时监控。首先对驾驶员的抽烟、玩手机、喝水行为进行目标检测;然后根据眼睛区域的Dlib关键点坐标信息计算眼睛纵横比EAR来衡量眼睛张开程度,根据合适的EAR阈值可判断睁眼或闭眼状态,并判断打哈欠的行为;最后基于EAR实测值和EAR阈值对监控视频计算闭眼时间比例(Perclos),度量驾驶员主观疲劳程度,将其与设定的疲劳度阈值进行比较即可判定是否疲劳驾驶。
本项目效果展示视频:
https://www.bilibili.com/video/BV1bj411S7rA/?share_source=copy_web&vd_source=138d2e7f294c3405b6ea31a67534ae1a
资源获取:
获取整套代码、测试视频、训练好的权重、说明文档和相应的目标检测数据集(有偿)
上交硕士,技术够硬,也可以指导深度学习毕设、大作业等。
-------------- 3582584734 ->qq ------------