基于MediaPipe 的疲劳检测系统设计与实现

作者: 郑定超

基于MediaPipe 的疲劳检测系统设计与实现0

摘要:针对疲劳驾驶、讲话分心等问题,文章提出了一种基于MediaPipe框架,结合人眼和嘴部特征的疲劳驾驶检测算法。相比传统单一面部特征检测,该算法首先采用MediaPipe框架对人面部区域进行快速定位,确定人眼和嘴部区域特征点。通过计算眼部纵横比及其持续时间和嘴部开合度及其动作频率作为判断疲劳驾驶的参数,因打哈欠、说话、频繁眨眼或闭眼等危险驾驶行为均会导致眼部和嘴部发生动作。最后对多参数进行加权平均计算与逻辑判断,确定目标是否处于疲劳驾驶状态。实验结果表明,基于MediaPipe框架结合人眼和嘴部特征的疲劳驾驶检测算法响应耗时为0.17毫秒,检测准确率达99.11%,较单一参数检测提高1.12个百分点。该算法提高了检测效率,具有较高的准确率和鲁棒性,满足驾驶员疲劳检测报警应用需求。

关键词:疲劳驾驶;状态检测;人脸识别;眼部纵横比

中图分类号:TP391.9 文献标识码:A

文章编号:1009-3044(2025)05-0011-04 开放科学(资源服务) 标识码(OSID) :

0 引言

疲劳会影响人的精神状态,降低其汽车驾驶能力,疲劳驾驶会使驾驶员的反应变慢,从而极易引发交通事故。2023年我国共发生交通事故25.5万起,数据表明21%的交通事故是由疲劳驾驶引起,占特大交通事故的40%以上,占交通事故死亡率的83%。因此,为驾驶员开发一套疲劳检测系统十分必要,以减少因疲劳引起的交通事故[1]。目前常用的检测方法有基于生理信号的检测,如脑电信号EEG、心电信号ECG、呼吸频率[2]等。这些方法具有较好的检测实时性,但需要佩戴仪器进行检测,检测成本较高,且对驾驶会造成一定的不便。随着计算机视觉技术的发展,可以获取驾驶员的行为特征作为数据来源进行分析,但目前检测的特征较为单一,容易造成误检和漏检。本研究考虑到打哈欠、说话等嘴部动作也是疲劳驾驶的表现之一,结合疲劳闭眼动作,设计了一个基于Me⁃diaPipe框架,结合眼部和嘴部特征共同检测的疲劳驾驶检测算法。基于该算法开发高可信度的疲劳驾驶检测系统,能够对驾驶员的眼睛、嘴巴区域进行数据采集分析,相互印证补充,避免因单一特征检测出现误报警现象,实现驾驶员疲劳检测报警应用功能,从而减少交通事故的发生。

1 系统设计

MediaPipe是一款开源的多媒体机器学习模型应用框架,内置了机器学习模型和功能块,可以快速、轻松地在程序中实现复杂的机器学习功能[3]。MediaPipe人脸检测除了提供面部边界框外,还可以输出6双眼中央、耳垂、嘴部中央与鼻尖等特征点的坐标,其轻量级特征提取网络使其在保持高精度的同时,能够在移动设备上快速运行。PERCLOS(Percentage of EyelidClosure over the Pupil over Time) 是指眼睛闭合时间占某一特定时间的百分率[4],其计算公式见式(1) 。驾驶员张开嘴可能有两种情况:一种是驾驶员打哈欠,处于疲劳状态;另一种是驾驶员不停地说话,处于分心状态。这两种情况都可能导致交通事故,因此口型运动的频率可以作为疲劳判断的依据。

PERCLOS = (眼睛闭合时间/总时间段) × 100% (1)

疲劳检测系统利用摄像头实时捕捉驾驶员脸部画面,并通过MediaPipe 框架进行人脸特征点检测。眼部区域通过计算眼睛的纵横比判断眼睛是否闭合,利用等效PERCLOS值判断人眼疲劳状态;嘴部区域则通过嘴巴的类圆度判断嘴巴是否张开,当张嘴状态持续超过阈值时判定为危险疲劳状态;最后对两者状态进行加权计算,从而判断驾驶员是否处于疲劳驾驶状态。系统流程如图1所示。

2 系统实现

系统利用普通摄像头进行视频获取,基于Media⁃Pipe框架,使用其提供的预训练模型和库,采用Python 编程进行图像检测处理。

2.1 模型的选择

人脸检测采用MediaPipe框架中的“Face Mesh”模型[5],该模型能够在单个摄像机输入下实时估计468个3D脸部界标,提供高效的实时性能。同时,该模型采用轻量级架构,减少计算负担,适合在资源有限的设备上运行。相比Dlib库检测人脸的68个关键点定位,MediaPipe可以估计468个人脸关键点。其内置了预训练模块及库,可以实时通过机器学习推断人脸表面几何形状,无需专门的深度摄像头进行检测,仅需普通摄像机输入图像即可,既降低了疲劳检测系统的硬件要求,又保证了视频图像处理效率。

使用MediaPipe进行人脸特征点检测的基本步骤如下:

1) 安装项目环境:项目采用Python 编程语言、OpenCV库、MediaPipe框架,首先须安装对应插件,命令如下:

pip install opencv-python

#0.10.13为本项目中所使用的版本,用户可以根据实际使用情况进行修改

pip install mediapipe== 0.10.13

2) 图像输入:视频数据的输入可以来自摄像头,也可以是视频,此次项目实验中,直接读取摄像头传入的视频图像数据,命令如下:

cap = cv2.VideoCapture(0)

3) 人脸关键点检测:初始化FaceMesh模块,读取摄像头传入的BGR彩色视频图像,转成RGB彩色图像,并调用库中的函数进行人脸特征点检测,命令如下:

imgRGB = cv2. cvtColor(img, cv2. COLOR_BGR2RGB)

#检测人脸关键点

results = faceMesh.process(imgRGB)

4) 关键点获取与绘制。

检测完人脸关键点后数据存入results中,通过循环遍历绘制特征点和边界框;为了后续方便得到特征点的坐标,同样通过循环输出关键点坐标,命令如下:

for faceLms in results.multi_face_landmarks:

mpDraw.draw_landmarks(img, faceLms, mpFaceMesh.FACEMESH_CONTOURS, drawSpec, drawSpec) # 绘制关键点

for id, lm in enumerate(faceLms.landmark):

ih, iw, ic = img.shape

x, y = int(lm.x * iw), int(lm.y * ih)

print(id, x, y)

人脸检测关键点绘制最终如图2所示。

利用“FaceMesh”模型可以检测人脸中的468个关键点,包括眼睛、鼻子、嘴巴、颧骨等部位,可根据需要选择特定的关键点进行使用[6]。

2.2 眼部区域状态检测及疲劳识别

根据人脸的468个特征点可获取人眼区域的特征点坐标信息。由于闭眼动作通常由两只眼睛同时发生,本节仅对左眼检测进行说明,实际项目中对两只眼睛均进行检测。眼部区域状态检测及疲劳识别步骤如下:

1) 标定左眼:确定左眼关键点的索引,通过循环遍历左眼的位置,以关键点为圆心进行标记,绘制出眼部区域,命令如下:

idList = [22, 23, 24, 26, 110, 157, 158, 159, 160,161, 130, 243] # 左眼坐标

for id in idList:

cv2.circle(img, tuple(face[id]), 4, (0,255,255), cv2.FILLED)

2) 计算人眼距离及纵横比:人在闭眼时,眼睛的上下边界距离会发生变化,而左右边界距离基本保持不变。由于人脸距离摄像头的远近会影响边界距离,人脸越靠近摄像机,眼眶间的距离就越小[7],因此不能仅通过距离判断是否闭眼。系统采用纵横比进行判断,即眼睛上下距离与左右距离之比。为提高计算效率与准确率,选取了6个眼部特征点,如图3所示。

眼睛纵横比公式见式(2) 。

EAR = ||P2 - P6|| + ||P3 - P5||/2||P1 - P4|| (2)

部分代码如下:

leftUp1 = face[158]

leftDown1 = face[22]

leftUp2 = face[160]

leftDown2 = face[24]

leftLeft = face[130]

leftRight = face[243]

cv2.line(img, leftUp1, leftDown1, (0, 200, 0), 3)

cv2.line(img, leftUp2, leftDown2, (0, 200, 0), 3)

cv2.line(img, leftLeft, leftRight, (0, 200, 0), 3)

lengthVer1 = int(detector.findDistance(leftUp1, left⁃Down1)[0])

lengthVer2 = int(detector.findDistance(leftUp2, left⁃Down2)[0])

lengthHor = int(detector.findDistance(leftLeft,leftRight)[0])

ratio = int(((lengthVer1+ lengthVer2) /(2* length⁃Hor)) * 100)

3) 眨眼判断及绘制图像:当眼睛发生闭合动作时,人眼距离纵横比会变小,达到30%时眯眼动作已十分明显。由于系统会对每一帧图像进行人眼距离纵横比计算,且正常的闭眼动作会持续多帧时间,为防止纵横比曲线波动较大,经过调试,系统设置当纵横比低于30%且持续时间超过10帧图像时则判定为闭眼疲劳动作,从而防止误检测。系统的眼部区域状态检测效果如图4所示。

2.3 嘴部区域状态检测及疲劳识别

根据人脸检测得到的特征点可获取嘴部区域的特征点坐标信息,无论是说话还是打哈欠均会引起嘴巴的开合。嘴部的特征点包括上唇内外侧、下唇内外侧共40个关键点,为简化计算,系统仅选取上下唇内侧部分特征点进行标记[8],如图5所示。

嘴部开合度计算的公式见公式(3) 。

MOUTH = |P2 - P6| + |P3 - P5|/2|P1 - P4| (3)

打哈欠时嘴巴会张开至相对较大的程度。根据相关研究和实践经验,嘴巴开合度阈值通常设定在0.5或0.6左右。由于打哈欠通常是一个持续时间较长的动作,可通过设置时长阈值来进一步确认是否发生打哈欠。根据实践经验,时长阈值通常设定在3秒或5秒左右。本系统经过调试,将嘴巴开合度阈值设为0.6,时长阈值设定为4秒。当计算结果大于0.6且持续时间超过4秒时,系统判定为疲劳驾驶并发出报警提醒,检测效果如图6所示。

3 实验结果与分析

医学数据统计表明,在正常情况下人每分钟眨眼10~15 次,每次眨眼和闭合的持续时间为0.1~0.2 秒;说话时每0.3~0.5秒发出一个音节,打哈欠时嘴巴张开持续时间为4~5秒[9]。系统采用加权平均方法,结合PERCLOS参数和嘴部动作频率参数共同检测疲劳状态,以最大限度地利用数据之间的冗余性和互补性。系统算法通过在不同情况下模拟驾驶疲劳状态进行测试,测试数据如表1所示。算法主要针对不同光照条件和不同驾驶员姿态进行测试,测试数据表明在光线充足的情况下准确率较高,而摄像头拍摄人脸的角度也会影响检测效果。同时,算法存在的误检和漏检现象可能与疲劳状态的持续时间有关。

经典小说推荐

杂志订阅