python项目:基于OpenCV的学生网课睡意检测系统

  • Post author:
  • Post category:python


代码链接:

https://download.csdn.net/download/qq_38361589/85467288?spm=1001.2014.3001.5503

目标睡意检测是计算机视觉的一个研究热点,随着未来教育日趋网络化,为了有效地提高学生网课学习质量,睡意检测系统对学生上课状态进行实时检测。

本系统基于OpenCv对学生面部进行定位,再通过Dlib内部实现的面部标志性检测器对学生面部特征进行提取,能够迅速有效地获取眼睛和嘴巴特征点的位置,再通过眼睛纵横比(Eye Aspect Ratio,EAR)和嘴巴纵横比(Mouth Aspect Ratio,MAR)结合计算帧数进行睡意判断



EAR背景介绍

在检测眼睛是闭眼还是睁眼中,国内国外均提出了众多研究方法。现有方法是主动的或被动的。主动方法是可靠的,但需使用特殊的硬件,

通常比较昂贵,例如红外摄像机和照明器,带有一个特殊的近摄相机来观察眼睛。显然,这些方法既昂贵又不方便,极其不适合应用于日常场景中。而针对无源系统,已经提出了许多方法来自动检测视频序列中的眨眼。一些方法是基于眼睛地区的运动估计。还有部分方法是检测眼睛是否被眼睑遮盖。另一种方法是推断状态从单个图像中睁开眼睛的角度,把睁眼和闭眼模板进行相关匹配。先前方法的主要缺点是从相对的意义上讲,它们通常对设备、脸部相机姿势(头部方向),图像分辨率,照明,运动动态等有过高要求。

强大的实时面部界标检测器可捕获人脸图像(包括眼睛)上的大多数特征点。正如Dlib,这些现代地标探测器经过“野外训练”数据集”,它们对于变化的光照,各种面部表情和适度的图像具有鲁棒性。最新探测器的地标定位平均误差通常低于眼间距离的百分之五。因此,我们提出一种简单而有效的算法–EAR,可以实现实时检测目标是否眨眼。



EAR

眨眼是人类眼睛的快速闭合和再睁开。每个人眨眼的方式都有点不同。这种模式在闭眼和开眼的速度、挤压眼睛的程度和眨眼的持续时间上有所不同。眨眼持续大约100-400毫秒。利用最先进的面部陆地标记探测器来定位眼睛和眼睑。从图像中检测到的地标,我们得到了眼睛长径比(EAR),用于估计睁眼状态。由于单帧耳朵不一定能正确识别眼睛的眨眼,因此训练了一个考虑帧的较大窗口的分类器我们依靠眼睛的纵横比例(EAR)来确定一个人是否眨眼。基于实际数据集使用面部关键点检测器作为输入,提出了简单有效的眨眼检测眨眼算法,通过定位眼睛和眼睑的轮廓得出眼睛的长宽比(Eye Aspect Ratio,EAR)人的眼睛长宽比(EAR),用于估计睁眼状态。



EAR特征应用

每只眼睛都由一组6个(x,y)坐标表示,该坐标从眼睛的左上角开始,然后围绕该区域的其余部分顺时针旋转. 右眼进行同理计算后,通过左右眼同步,将得到的左右眼两个EAR进行平均后得出最终结果。

图2.3 眼睛坐标

上图中的6个特征点p1至p6是人脸特征点中对应眼睛的6个特征点。这些坐标的宽度和高度之间有一个关系,将访问到的左眼数据[43,48]进行编号。

同时,计算了嘴长宽比(MAR),提取坐标62、64、66和68来计算两者之间的距离,方法与EAR计算相同。



检测系统



眨眼检测

使用OpenCV进行检测是目前比较常用的人脸检测算法,该算法在进行图像检测时具有较高的准确性和实时性。与用于计算眨眼的传统图像处理方法不同,OpenCV检测和计数视频流中的眨眼的方法如下:

(1)定位眼睛的位置

(2)通过阈值找到黑色的眼睛

(3)计算眼睛的“黑色”区域消失的帧数

这种眨眼检测方法非常快速,并且高效且易于实现。此方法应用脸部界标检测来定位脸部重要区域,包括眼睛,眉毛,鼻子,耳朵和嘴巴。

首先检测到眼睛,每只眼睛均由6 个(x,y)坐标表示,从眼睛的左角开始,然后沿该区域的其余部分顺时针旋转:

在这里插入图片描述

眼睛纵横比(EAR):

在这里插入图片描述

其中 p1,…,p6是2D面部界标位置。

该方程的分子计算垂直眼界标之间的距离,而分母计算水平眼界标之间的距离,对分母进行适当加权,只有一组水平点,但有两个两组垂直点。睁开眼睛时眼睛的纵横比大约是恒定的,但是当眨眼时眼睛的纵横比会迅速降至零。通过使用这个简单的方程式,我们可以避免使用图像处理技术,而只需要依靠眼睛界标距离的比率来确定人是否眨眼。

在这里插入图片描述
图 左上方:睁开眼睛时眼睛的坐标可视化 右上:闭上眼睛时的眼睛坐标 底部:绘制随时间变化的眼睛纵横比(眼睛纵横比的下降表示眨眼)

在左上方实验者的眼睛完全张开,此处的眼睛长宽比会很大(r),并且随着时间的推移相对恒定。但是,一旦实验者眨眼(右上角),眼睛的纵横比就会急剧下降,接近零。在底部图中绘出了眼纵横比随时间的视频剪辑的曲线图。如图所示,眼睛的纵横比是恒定的,然后迅速下降到接近零,然后再次增加,表明发生了一次眨眼行为。



哈欠检测

嘴巴纵横比(MAR):

![在这里插入图片描述](https://img-blog.csdnimg.cn/dd55019f0ab54d849ac7b7b063ffa765.png =600)

其中 p13,…,p19是2D面部界标位置。

该方程表示嘴巴的张合程度,打哈切的时候嘴巴纵横比大约是恒定的,但是当实验者不打哈欠的时候嘴巴的纵横比会迅速降至零。我们可以通过计算嘴巴的纵横比不为0的帧数,证明实验者是正在打呵欠。并且此时若是检测到实验者闭着眼睛,则表明实验者困意正浓,需要系统做出反应发出警报提醒实验者保持清醒。



睡意检测

睡意检测的情况下,通过监视眼睛的纵横比,若若眼睛的纵横比持续数帧为0,那么就表示是实验者已经睡着了,并不是实验者的眨眼行为。

使用OpenCV进行人脸检测算法流程如图所示:

在这里插入图片描述



方法

使用 dlib 的界标预测器检测面部中的面部界标。 地标预测器返回代表面部不同区域的 68 个 (x, y) 坐标,即 – 嘴巴、左眉、右眉、右眼、左眼、鼻子和下巴。 当然,我们不需要所有的地标,这里我们只需要提取眼睛和嘴巴区域。

def eye_aspect_ratio(eye):
	# Vertical eye landmarks
	A = dist.euclidean(eye[1], eye[5])
	B = dist.euclidean(eye[2], eye[4])
	# Horizontal eye landmarks 
	C = dist.euclidean(eye[0], eye[3])

	# The EAR Equation 
	EAR = (A + B) / (2.0 * C)
	return EAR

眼睛区域由 6 个坐标标记。 如果用某个阈值检查 EAR 的值,这些坐标可以用来确定眼睛是睁着还是闭着。

blink_detection_plot

以同样的方式,计算嘴的纵横比来检测一个人是否在打哈欠。 从上唇和下唇各取了 2 个点,并计算了它们之间的平均距离:

def mouth_aspect_ratio(mouth): 
	A = dist.euclidean(mouth[13], mouth[19])
	B = dist.euclidean(mouth[14], mouth[18])
	C = dist.euclidean(mouth[15], mouth[17])

	MAR = (A + B + C) / 3.0
	return MAR

上述内容仅用于学习,仅供参考,切勿抄袭。



版权声明:本文为qq_38361589原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。