基于dlib人脸识别68特征点检测、分别获取左右眼面部标志的索引,通过opencv对视频流进行灰度化处理,检测出人眼的位置信息。
人脸特征点检测用到了dlib,dlib有两个关键函数:dlib.get_frontal_face_detector()和dlib.shape_predictor(predictor_path)。
前者是内置的人脸检测算法,检测人脸区域的界限
后者是用来检测一个区域内的特征点,并输出这些特征点的坐标,它需要一个预先训练好的模型(通过文件路径的方法传入),才能正常工作。
使用开源模型shape_predictor_68_face_landmarks.dat,可以得到68个特征点位置的坐标
点我下载开源数据集
基本原理:计算 眼睛长宽比EAR.当人眼在正常状态下时,EAR在某个值上下波动,当人眼闭合时,EAR迅速下降。所以我们认为当EAR低于某个阈值时,眼睛处于闭合状态。为检测眨眼次数,我们设置了阈值为0.2,如果当前帧两双眼睛宽高比的平均值小于0.2,则加1,如果连续3次都小于阈值,则表示进行了一次眨眼活动。
(68点landmark中可以看到37-42为左眼,43-48为右眼)
右眼开合度可以通过以下公式得到(左眼同理):
通过计算38、39、42、41的纵坐标、37、40的横坐标来计算眼睛的睁开度。如:1/2*[(y42+y41)-(y38+y39)]/(x40-x37)通过一个阈值确定眼睛是睁开还是闭上。也可以将这个值与初始的值的比值作为睁开度,根据不同程度来进行比较。睁开度从大到小为进入闭眼期,从小到大为进入睁眼期,计算 最长闭眼时间(可用帧数来代替)闭眼次数为进入闭眼、进入睁眼的次数 。
主要代码思路
第一步:使用dlib.get_frontal_face_detector() 获得脸部位置检测器
第二步:使用dlib.shape_predictor获得脸部特征位置检测器
第三步:分别获取左右眼面部标志的索引
第四步:打开cv2 本地摄像头
第五步:从视频流进行循环,读取图片,并对图片做维度扩大,并进灰度化
第六步:使用detector(gray, 0) 进行脸部位置检测
第七步:循环脸部位置信息,使用predictor(gray, rect)获得脸部特征位置的信息
第八步:将脸部特征信息转换为数组array的格式
第九步:提取左眼和右眼坐标
第十步:构造函数计算左右眼的EAR值,使用平均值作为最终的EAR
第十一步:使用cv2.convexHull获得凸包位置,使用drawContours画出轮廓位置进行画图操作
第十二步:进行画图操作,用矩形框标注人脸
第十三步:分别计算左眼和右眼的评分求平均作为最终的评分,如果小于阈值,则加1,如果连续3次都小于阈值,则表示进行了一次眨眼活动
第十四步:进行画图操作,68个特征点标识
第十五步:进行画图操作,同时使用cv2.putText将眨眼次数进行显示
嘴部主要取六个参考点:
打哈欠可利用嘴巴处通过计算51、59、53、57、的纵坐标、49、55的横坐标来计算眼睛的睁开度。如:1/2*[(y51+y53)-(y59+y57)]/(x55-x49)点的距离来判断是否张嘴及张嘴时间,从而确定人是否是在打哈欠,同时这个阈值应当合理,能够与正常说话或哼歌区分开来。
同眼睛相类似方法求嘴部欧式距离:
主要代码思路
Step1:提取帧图像检测人脸,嘴部粗定位进行肤色分割;
Step2: 嘴部精确定位,获取嘴部欧式距离K1,若k1大于阈值T1,则Step3,并且count+1;否则count=0回到step1,检测下一帧。
Step3: 统计哈欠特征值count,当count超过阈值3,则记作打一次哈欠,保存count到Yawn,Yawn(i)=count,count=0(count清0)回到Step1,否则的话也直接转回Step1。
采用Head Pose Estimation(头部姿态估计) 算法,该算法的步骤一般为:2D人脸关键点检测;3D人脸模型匹配;求解3D点和对应2D点的转换关系;根据旋转矩阵求解欧拉角
https://developer.aliyun.com/article/674048
https://blog.csdn.net/lql0716/article/details/72597719
具体原理请看上面那两篇博客,网上有开源代码(如下),大神已经帮我们搞好了,我们拿来直接用就行,最后得到欧拉角
点我查看参考代码
主要代码思路
头部姿态判断打瞌睡得到实时头部姿态的旋转角度过后,如下所示为头部旋转角度的3个参数Yaw,Pitch和Roll的示意图,驾驶员在打瞌睡时,显然头部会做类似于点头和倾斜的动作.而根据一般人的打瞌睡时表现出来的头部姿态,显然很少会在Yaw上有动作,而主要集中在Pitch和Roll的行为.设定参数阈值为0.3,在一个时间段内10 s内,当I PitchI≥20°或者|Rolll≥20°的时间比例超过0.3时,就认为驾驶员处于点头打瞌睡的状态
我们分别计算出单位时间内瞌睡点头的频率,眨眼频率以及打哈欠的频率分别赋予他们不同的权值,采用信息融合的方式进行综合打分,最后根据最终分数,设置疲劳等级,分别为轻度疲劳,中度疲劳和重度疲劳,相应的做出报警等操作,可自行观看源代码理解
DONE | |
---|---|
DONE | |
DONE | |
DONE | |
DONE | |
DONE | |
DONE | |
DONE | |
DONE | |
DONE | |
DONE |
Blinks | 眨眼次数 |
---|---|
Yawning | 打哈欠次数 |
Nod | 瞌睡点头次数 |
Blink Frequency | 实时眨眼频率 |
Yawing Frequency | 实时打哈欠频率 |
Nod Frequency | 实时瞌睡点头频率 |
Score | 疲劳程度 |
FPS | 视频帧率 |
main.py-------------------------主程序
sats2.py--------------------------报表界面制作(pyecharts,感觉还是挺好用的,具体操作可以看官网文档,中国人开发的库值得推荐)
pyecharts gallery pyecharts操作手册
images目录下存放图片png以及ico
model目录下存放68人脸关键点模型
fatigue_detect.html-----------------可视化报表
私信我获取完整源代码
https://blog.csdn.net/cungudafa/article/details/103477960
https://blog.csdn.net/cungudafa/article/details/103499230
https://blog.csdn.net/cungudafa/article/details/103496881
https://blog.csdn.net/lql0716/article/details/72597719
https://developer.aliyun.com/article/674048