【计算机视觉40例】案例38:驾驶员疲劳监测

《计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论入门的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面(表情识别、驾驶员疲劳监测、识别性别与年龄等)案例。

本文简要截取书中第38个案例(驾驶员疲劳监测)的部分内容。更多内容大家可以参考书中第28章《人脸识别应用》。

疲劳驾驶极易引起交通事故,其一个重要表现就是犯困,眼睛会在超过正常眨眼的时间内一直处于闭合状态。因此,可以通过眼睛的纵横比(高宽比)来判断眼睛是否闭合(眨眼),进而判断驾驶员是否处于疲劳驾驶状态。

如图1所示,对睁眼、闭眼的情况进行了演示,其中:

  1. 左侧是正常的睁眼状态,眼睛的高度与宽度的比值在0.3左右。
  2. 右侧是闭眼(眨眼)状态,眼睛的高度与宽度的比值在0左右。

1 眼睛模型

具体来说,Dlib使用6个关键点来标注眼睛,因此其高宽比的计算方式为:

下一步,需要判断正常的眨眼和长时间闭眼(疲劳)的区别。正常情况下,眨眼是一瞬间,而疲劳的闭眼是相对较长时间的。例如,在图2中:

  1. 上图中,高宽比仅仅在一瞬间处于较小值(约0),其余时间都是正常值(约0.3),此时对应的是正常眨眼。
  2. 下图中,高宽比在某一个较长时间内都处于较小值(约0),此时对应的是长时间闭眼。如果它的时长超过了我们事先规定的阈值,则将该状态判定为疲劳状态。

2  眼睛高宽比

因此,在判断眼睛高宽比的基础上,还要衡量眼睛高宽比所持续的时间。反映到视频帧中,要增加一个计数器,该计数器的工作方式为:

  1. 眼睛高宽比小于0.3时,认为当前帧眼睛处于闭合状态,计数器加1。并判断计数器的值,如果计数器大于阈值(例如48),则认为眼睛闭合的时间过长了,提示风险;如果小于等于阈值认为眼睛闭合的时间在正常范围内,当前的闭眼,仅仅是眨眼,无需任何额外处理。
  2. 眼睛高宽比大于等于0.3时,当前帧眼睛处理睁开状态,将计数器清零。保证下次闭眼时,计数器能够从零开始重新计数。

根据上述分析,具体实现流程图如图3所示。

3 流程图

本案例中,使用到了Dlib,它是一个现代工具包,包含机器学习算法和工具,用于在程序中构造软件来解决复杂的现实世界问题。它被工业界和学术界广泛应用于机器人、嵌入式设备、移动电话和大型高性能计算环境等领域。Dlib的开源许可允许用户在任何应用程序中免费使用它。

【核心代码截取(书中附有全部代码)】使用Dlib进行疲劳检测。

# ==============获取图像内的左眼、右眼对应的关键点集==============

def getEYE(image,rect):

    landmarks=predictor(image, rect)

    # 关键点处理为(x,y)形式

    shape = np.matrix([[p.x, p.y] for p in landmarks.parts()])

    # 计算左眼、右眼

    leftEye = shape[42:48]   #左眼,关键点索引从42到47(不包含48)

    rightEye = shape[36:42]  #右眼,关键点索引从36到41(不包含42)

    return leftEye,rightEye

# ============计算眼睛的纵横比(小于0.3太小是闭眼或眨眼、超过0.3是睁眼)==========

def eye_aspect_ratio(eye):

    # 眼睛用6个点表示。上下各两个,左右一个,结构如下所示:

    #---------------------------------------------

    #      1    2

    # 0             3      <----这是眼睛的6个关键点

    #      5    4

    #---------------------------------------------

    # 欧氏距离(垂直方向上的两个距离1和5、 2和4)

    A = dist.euclidean(eye[1], eye[5])

    B = dist.euclidean(eye[2], eye[4])

    # 欧氏距离(水平距离0和3)

    C = dist.euclidean(eye[0], eye[3])

    #纵横比

    ear = (A + B) / (2.0 * C)

    return ear

# ================计算两眼的纵横比均值========================

def earMean(leftEye,rightEye):

    # 计算左眼纵横比leftEAR、右眼纵横比rightEAR

    leftEAR = eye_aspect_ratio(leftEye)

    rightEAR = eye_aspect_ratio(rightEye)

    # 均值处理

    ear = (leftEAR + rightEAR) / 2.0 

    return ear

# ==============绘制眼框(眼眶的包围框)=======================

def drawEye(eye):

    # 把眼睛圈起来1:convexHull,获取凸包

    eyeHull = cv2.convexHull(eye)

    # 把眼睛圈起来2:drawContours,绘制凸包对应的轮廓

    cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0), 1)

运行结果如图2所示,当眼睛的高宽比长时间低于阈值时,会显示危险提示“DANGEROUS!!!”。

图2 效果显示 

第28章《人脸识别应用》中还介绍了人脸表情识别、易容术、识别性别年龄等案例的基本原理和实现过程。欢迎大家在《计算机视觉40例——从入门到深度学习(OpenCV-Python)》第28章《人脸应用案例》中获取更详细的内容。

书中包含的人脸识别相关案例有:

  1. 人脸检测
  2. 人脸识别
  3. 勾勒五官
  4. 人脸对齐
  5. 表情识别
  6. 疲劳驾驶检测
  7. 易容术
  8. 性别与年龄识别

  • 1
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

superdont

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值