当前位置: 首页 > news >正文

计算机视觉(opencv)——疲劳检测

疲劳检测系统详解与实现(驾驶员/课堂监控)

摘要

疲劳检测是一类通过分析人体行为(如眼睛闭合、头部姿态、打哈欠等)来判断个体是否处于疲劳或注意力不集中的技术。它在驾驶员监控、驾驶安全、课堂学员状态检测、远程办公督导等场景中具有重要应用价值。本文以基于人脸关键点的眼睛纵横比(EAR, Eye Aspect Ratio)方法为基础,详细介绍原理、代码实现、参数调优、实际部署建议与改进方向,文末给出完整可运行的示例代码(含中文显示与眼睛凸包绘制)。


1. 背景与动机

疲劳导致的注意力下降会显著增加事故风险。传统基于车辆行驶特征(如车道偏离、方向盘行为)的疲劳检测受限于车辆传感器;基于生理信号(如EEG、心率)的方案则需要佩戴设备。视觉感知方案利用摄像头采集面部图像,通过计算机视觉方法无侵入地判断疲劳状态,部署成本较低、易扩展,是当前研究与工程应用的主流方向之一。

应用场景举例:

  • 驾驶员监控(车载摄像头):及时提醒疲劳驾驶的驾驶员,或与车辆控制系统联动减速。

  • 学员上课状态检测:判断学生是否走神、打瞌睡,辅助教师或远程学习平台统计学习投入度。

  • 工业作业监控:对高危岗位作业人员进行实时监护。


2. 方法概述:基于EAR的闭眼检测

眼睛纵横比(EAR)由Soukupová 和 Čech 提出,基于眼睛的 6 个关键点位置计算。EAR 的优点在于:计算量小、对头部轻微转动具有鲁棒性、实时性好。其计算公式为:

[EAR = \frac{|p_2 - p_6| + |p_3 - p_5|}{2 \cdot |p_1 - p_4|}]

其中 p1~p6 为眼睛轮廓的 6 个关键点(见文中代码注释)。当眼睛闭合时,EAR 会显著下降;通过对连续帧的 EAR 设阈值与持续帧数,可以区分瞬时眨眼与真正的闭眼(疲劳/打瞌睡)。

优点与局限

  • 优点:无需训练复杂模型,简单高效,适合资源受限场景。

  • 局限:对遮挡(手、眼镜的强反光)、极端侧脸与光照变化敏感;单纯使用 EAR 无法区分打瞌睡与短暂低头等情况,通常需要结合头部姿态与 yaw/pitch/roll 或面部表情(如打哈欠)来提升准确率。


3. 代码实现说明(含关键步骤讲解)

下面的示例代码实现了基于 dlib 的人脸检测与 68 点关键点定位,计算左右眼 EAR,绘制眼睛凸包并在疲劳(连续闭眼超过阈值)时给出中文报警提示。代码包含:

  • eye_aspect_ratio(eye):计算单侧眼睛 EAR;

  • cv2AddChineseText:使用 PIL 在 OpenCV 图像上绘制中文(需要本地字体如 simsun.ttc);

  • drawEye:绘制眼眶凸包以便可视化;

  • 主循环:获取摄像头帧、检测人脸、计算 EAR、判断是否疲劳并报警。

import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances  # 计算欧氏距离
from PIL import Image, ImageDraw, ImageFont  # pip install pillowdef eye_aspect_ratio(eye):'''-------------计算眼睛纵横比-------------#    1   2# 0         3   <----这是眼睛的6个关键点#    5   4'''A = euclidean_distances(eye[1].reshape(1, 2), eye[5].reshape(1, 2))B = euclidean_distances(eye[2].reshape(1, 2), eye[4].reshape(1, 2))C = euclidean_distances(eye[0].reshape(1, 2), eye[3].reshape(1, 2))ear = ((A + B) / 2.0) / C  # 纵横比return eardef cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=30):"""向图片中添加中文"""if (isinstance(img, np.ndarray)):  # 判断是否OpenCV图片类型img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 步骤array转image的转换draw = ImageDraw.Draw(img)  # 在图片上创建一个绘图的对象# 字体的格式fontStyle = ImageFont.truetype("simsun.ttc", textSize, encoding="utf-8")draw.text(position, text, textColor, font=fontStyle)  # 绘制文本return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)  # 转换回OpenCV格式def drawEye(eye):  # 绘制眼眶凸包eyeHull = cv2.convexHull(eye)cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0), 1)COUNTER = 0  # 闭眼持续次数统计
detector = dlib.get_frontal_face_detector()  # 构造脸部位置检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")  # 读取人脸关键点定位模型
cap = cv2.VideoCapture(0)while True:ret, frame = cap.read()faces = detector(frame, 0)  # 获取人脸for face in faces:  # 循环遍历每一个人脸shape = predictor(frame, face)  # 获取关键点# 将关键点转换为坐标(x,y)的形式shape = np.array([[p.x, p.y] for p in shape.parts()])rightEye = shape[36:42]  # 右眼,关键点索引从36到41(不包含42)leftEye = shape[42:48]  # 左眼,关键点索引从42到47(不包含48)rightEAR = eye_aspect_ratio(rightEye)  # 计算右眼纵横比leftEAR = eye_aspect_ratio(leftEye)  # 计算左眼纵横比ear = (leftEAR + rightEAR) / 2.0  # 均值处理if ear < 0.3:  # 小于0.3认为闭眼,也可能是眨眼COUNTER += 1  # 每检测到一次,将+1if COUNTER >= 50:  # 持续50帧都闭眼,则警报frame = cv2AddChineseText(frame, "!!!!!危险!!!!! ", (250, 250))# 宽高比>0.3,则计数器清零、解除疲劳标志else:COUNTER = 0  # 闭眼次数清零drawEye(leftEye)  # 绘制左侧凸包drawEye(rightEye)  # 绘制右侧凸包info = "EAR: {:.2f}".format(ear[0][0])frame = cv2AddChineseText(frame, info, (0, 30))  # 显示眼睛闭合程度值cv2.imshow("Frame", frame)# 捕获按键key = cv2.waitKey(1)# 如果按下Ecs键,则退出(Esc的ASCII码为27)if key == 27:break
cv2.destroyAllWindows()
cap.release()

说明:示例中使用 shape_predictor_68_face_landmarks.dat(dlib 提供的 68 点模型),以及 simsun.ttc 字体用于中文显示。请确保这些文件路径在运行环境中可用。


4. 参数与阈值调整建议

关键超参数:

  • EAR 阈值(示例中为 0.3):该值与拍摄角度、相机分辨率、被检测者眼型有关。可通过离线标注数据集(含张眼、闭眼样本)计算 ROC 曲线以选取最优阈值。

  • 连续帧数阈值(示例中为 50 帧):与摄像头帧率相关。若帧率为 30 FPS,50 帧约为 1.6 秒;对于疲劳检测通常选择 1–2 秒范围来区分眨眼(短于 0.4s)与长时间闭眼。

调优步骤建议:

  1. 记录视频/样本,包含正常眨眼、短时闭眼与疲劳闭眼的多样本;

  2. 在不同阈值下统计误报与漏报率,绘制 F1-Score 或 ROC,从而选择平衡点;

  3. 在线场景中可启用自适应阈值(例如基于初始化阶段记录的用户基线 EAR 的均值和方差进行动态归一化)。


5. 抗干扰与鲁棒性提升方法

为了在复杂环境(强光、侧脸、眼镜)下仍保持性能,可考虑:

  • 使用更强健的人脸关键点检测器(例如基于深度学习的关键点检测网络)来替代 dlib 的 68 点预测器;

  • 融合头部姿态估计(yaw/pitch/roll):若头部过度低头或侧转,暂时降低 EAR 的权重并结合面部朝向判断是否为真实疲劳;

  • 使用红外或近红外摄像头:在夜间或强逆光环境有明显优势;

  • 增加多模态输入:口部张开、打哈欠检测、面部肌肉活动等共同决策以降低单一指标误报率;

  • 使用时间序列模型:例如 LSTM 或 1D 卷积对 EAR 序列建模,能够更好地区分短时眨眼与长期闭眼。


6. 实际工程中的部署考量

硬件选择

  • 车载场景建议选择宽动态(WDR)摄像头或红外摄像头以适应光照变化;

  • 校园/教室场景可以使用普通高清摄像头,注意视角覆盖与分辨率保证眼部关键点的可见性(建议人脸像素高度在 80px 以上)。

性能与延迟

  • EAR 方法极轻量,可在单核 CPU 或边缘设备(如 Raspberry Pi 4、NVIDIA Jetson Nano)上实现实时运行;

  • 若采用深度学习关键点检测或多模态融合,建议使用带 GPU 的边缘设备或把计算放在本地服务器上。

隐私与合规

  • 摄像头监控涉及个人隐私与法规合规(如 GDPR、各地隐私法),应在部署前明确通知被监控者、限定数据存储时间、并采取加密与权限控制措施;

  • 对数据进行去标识化处理仅保存统计结果(如疲劳次数、注意力得分)可降低隐私风险。


7. 常见问题与排查

Q:为何 EAR 值计算异常(例如为 NaN 或极大值)?

  • A:通常是因为关键点定位失败或某些点重合。建议在计算前检测关键点是否完整、并加入异常值过滤(例如当 C(水平距离)为 0 或过小,跳过该帧)。

Q:佩戴眼镜会影响检测?

  • A:反光或深色镜片会降低关键点检测准确性。解决方式包括使用更多鲁棒的关键点检测器、使用 IR 摄像头或在检测失败时退回基于脸部姿态与其他特征的判断。

Q:如何降低误报(把头低看手机被误判为疲劳)?

  • A:结合头部俯仰角(pitch)与面部朝向,当检测到明显低头且眼睛闭合时,先判为“低头行为”,结合时间序列判断是否超过疲劳持续阈值后再报警。


8. 改进方向(研究与工程)

  1. 多模态融合:结合眼睛、嘴部(打哈欠)、头部姿态与驾驶行为数据(方向盘输入)实现更鲁棒的疲劳判定;

  2. 个体化模型:引入在线学习机制,根据用户基线 EAR 动态调整阈值;

  3. 轻量化深度模型:使用 MobileNet/ShuffleNet 系列训练专用关键点检测或疲劳分类器,便于在边缘设备上高效运行;

  4. 异常场景检测:对遮挡、多人场景、夜间等情形建立检测策略及回退机制。


9. 如何评估系统效果

评估指标包括准确率(Accuracy)、精确率(Precision)、召回率(Recall)、F1-Score;对于实时系统,还应统计平均响应延时与误报率(False Alarm Rate)。

建议构建包含多样性(不同年龄、性别、戴/不戴眼镜、不同光照与角度)的测试集,并使用交叉验证评价阈值与模型的泛化能力。


10. 总结与建议

基于 EAR 的疲劳检测是一条工程上可快速落地的路径,适合对实时性要求高、计算资源受限的场景。为了提高鲁棒性,建议将 EAR 与头部姿态、面部表情(如打哈欠)以及时间序列分析结合,采用多模态判定策略;在部署前则需考虑隐私合规与用户告知机制。

如果你希望,我可以:

  • 将上述代码改写为模块化的可复用函数(支持多人检测、日志记录与事件回放);

  • 帮你设计实验流程与标注工具来调参并评估模型;

  • 给出基于深度关键点检测器或轻量化网络的替代实现示例(含性能对比)。


依赖与运行提示

  • Python 版本建议 3.7+;

  • 依赖库:dlib, opencv-python, numpy, scikit-learn(或直接使用 numpy.linalg.norm 替代欧氏距离函数)、Pillow

  • 需要下载 shape_predictor_68_face_landmarks.dat(dlib 官方提供)并确保 simsun.ttc 或其他中文字体可用。

本文档包含完整代码与详细注释,方便复制运行与工程化改造。

http://www.dtcms.com/a/454188.html

相关文章:

  • 网站建设与运营的预算方案模板做图骂人的图片网站
  • 网站开发报告参考文献安卓优化大师最新版
  • 【代码随想录算法训练营——Day28】贪心算法——452.用最少数量的箭引爆气球、435.无重叠区间、763.划分字母区间
  • 企业在建设自己网站时哪个网站可以免费做推广
  • 数据备份-从策略到实战
  • 598网站建设推广渠道有哪些
  • 一文畅览 Qt 控件类
  • 高校网站建设招标公告企业网站模板推荐
  • 网站建设所需域名百度推广优化是什么?
  • 网站的颜色搭配专业营销网站开发
  • 第八个实验——浮动路由
  • 西安网站建设云阔网络熊掌号网站建设骗
  • 爱唐山做贡献月评十佳投票网站网站空间稳定性
  • 江苏省城乡建设网站玉溪做网站的公司
  • 专业柳州网站建设多少钱中卫网站推广营销
  • 付网站首期合同款怎么做分录彩票网站wordpress模板
  • 数据合规不是法律选择题:当数据边界成为商业战场
  • 网站设计企网站集约化建设的目的
  • 手机网站的文本排版是怎么做的如何写一个wordpress主题
  • OKZOO亮相TOKEN2049,展示AIoT网络生态新蓝图HealthFi
  • 淮安集团网站建设济南 域名注册 网站建设
  • B012基于博途西门子1200PLC温室大棚控制系统仿真
  • 机房网站建设方案个人资讯网站建设
  • 邯郸北京网站建设WordPress滑动验证码插件
  • 做网站要服务器和什么wordpress 点赞分享
  • 网站建设要学哪些软件有哪些内容网站开发用台式机电脑配置
  • C++----哈希以及unorder map与set的封装
  • 网站开发框架具体使用方法wordpress创建分类目录
  • 百度网站收录删除网站推广的公司
  • flash 的网站西安制作网站