news 2026/7/12 6:38:47

【深度学习】dlib 人脸关键点实时疲劳检测

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【深度学习】dlib 人脸关键点实时疲劳检测

文章目录

  • 完整代码一览
  • 环境准备与模型下载
  • 核心原理:眼睛纵横比(EAR)
  • 逐行代码详解
    • 导入库
  • EAR 计算函数
  • 中文绘制函数
  • 绘制眼睛轮廓
  • 主程序
  • 主循环

完整代码一览

import numpy as np import dlib import cv2 from sklearn.metrics.pairwise import euclidean_distances from PIL import Image,ImageDraw,ImageFont # 计算眼睛EAR纵横比 defeye_aspect_ratio(eye):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)/Creturnear # 绘制中文文字 defcv2AddChineseText(img,text,position,textColor=(255,0,0),textSize=50):ifisinstance(img,np.ndarray):img=Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))draw=ImageDraw.Draw(img)fontStyle=ImageFont.truetype("simhei.ttf",textSize,encoding="utf-8")draw.text(position,text,textColor,fontStyle)returncv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)# 绘制眼睛轮廓 defdrawEye(eye):eyeHull=cv2.convexHull(eye)cv2.drawContours(frame,[eyeHull],-1,(0,255,0),2)COUNTER=0detector=dlib.get_frontal_face_detector()predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")cap=cv2.VideoCapture(0)whileTrue:ret,frame=cap.read()ifnot ret:breakfaces=detector(frame,0)forface in faces:shape=predictor(frame,face)shape=np.array([[p.x,p.y]forp in shape.parts()])rightEye=shape[36:42]leftEye=shape[42:48]rightEAR=eye_aspect_ratio(rightEye)leftEAR=eye_aspect_ratio(leftEye)ear=(leftEAR+rightEAR)/2.0ifear<0.3:COUNTER+=1ifCOUNTER>=30:frame=cv2AddChineseText(frame,"!!!!危险!!!!",(250,250))else:COUNTER=0drawEye(leftEye)drawEye(rightEye)info="EAR: {:.2f}".format(ear[0][0])frame=cv2AddChineseText(frame,info,(0,30))cv2.imshow("Frame",frame)ifcv2.waitKey(1)==27:breakcap.release()cv2.destroyAllWindows()

环境准备与模型下载

import numpy as np import dlib import cv2 from sklearn.metrics.pairwise import euclidean_distances #计算欧氏距离 from PIL import Image,ImageDraw,ImageFont

dlib安装可以看博主的另外一篇文章了解,本文不过多赘述:
【深度学习】dlib 人脸关键点检测

核心原理:眼睛纵横比(EAR)

EAR(Eye Aspect Ratio)是衡量眼睛张开程度的一个指标。

  • 上眼睑左点:A
  • 上眼睑右点:B
  • 右眼角:C
  • 下眼睑右点:D
  • 下眼睑左点:E
  • 左眼角:F

EAR = (||A-E|| + ||B-D||) / (2 * ||F-C||)

分子是两只眼睛垂直方向的平均距离(约等于眼睛高度),

分母是水平方向的距离(约等于眼睛宽度)。

当眼睛睁开时,EAR 值较大(约 0.25~0.3);当眼睛闭合时,EAR 急剧减小(接近 0)。我们设定一个阈值(如 0.3),即可判断睁闭眼。

逐行代码详解

导入库

import numpy as np #数组操作 import dlib #人脸检测 import cv2 #图像处理 from sklearn.metrics.pairwise import euclidean_distances #计算欧氏距离 from PIL import Image,ImageDraw,ImageFont

EAR 计算函数

defeye_aspect_ratio(eye):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)/Creturnear

EAR公式:(A+B)/(2*C)
eye 是包含 6 个点坐标的 NumPy 数组,形状为 (6, 2)。

按照 dlib 的索引顺序,0 和 3 是水平两端,1和5、2和4 是垂直两对。

计算三组距离,代入公式得到 EAR。注意返回的 ear 是一个 (1,1) 数组,后面取值时需用 ear[0][0]。

中文绘制函数

defcv2AddChineseText(img,text,position,textColor=(255,0,0),textSize=50):ifisinstance(img,np.ndarray):img=Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))draw=ImageDraw.Draw(img)fontStyle=ImageFont.truetype("simhei.ttf",textSize,encoding="utf-8")draw.text(position,text,textColor,fontStyle)returncv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR)

将 OpenCV 的 BGR 图像转为 PIL 的 RGB 图像,绘制文字后再转回 BGR。

绘制眼睛轮廓

defdrawEye(eye):eyeHull=cv2.convexHull(eye)cv2.drawContours(frame,[eyeHull],-1,(0,255,0),2)

cv2.convexHull 计算眼睛点的凸包,然后绘制绿色轮廓线,用于直观显示眼睛区域。

主程序

COUNTER=0detector=dlib.get_frontal_face_detector()predictor=dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")cap=cv2.VideoCapture(0)

COUNTER 用于统计连续闭眼帧数。

初始化检测器、预测器,打开默认摄像头。

主循环

whileTrue:ret,frame=cap.read()ifnot ret:breakfaces=detector(frame,0)

逐帧读取,检测人脸。

forface in faces:shape=predictor(frame,face)shape=np.array([[p.x,p.y]forp in shape.parts()])rightEye=shape[36:42]leftEye=shape[42:48]rightEAR=eye_aspect_ratio(rightEye)leftEAR=eye_aspect_ratio(leftEye)ear=(leftEAR+rightEAR)/2.0

提取 68 点,分别截取左右眼的 6 个点(注意 dlib 中右眼是 36~41,左眼是 42~47)。

分别计算两眼的 EAR,取平均值作为最终的 ear。

ifear<0.3:COUNTER+=1ifCOUNTER>=30:frame=cv2AddChineseText(frame,"!!!!危险!!!!",(250,250))else:COUNTER=0

如果 EAR 低于阈值 0.3,说明眼睛闭合,计数器加 1。

当连续闭眼超过 30 帧,判定为疲劳瞌睡,在画面中央显示红色警告文字。

一旦睁眼,计数器清零。

drawEye(leftEye)drawEye(rightEye)info="EAR: {:.2f}".format(ear[0][0])frame=cv2AddChineseText(frame,info,(0,30))

绘制眼睛轮廓,并在屏幕左上角显示当前的 EAR 数值,方便调试。

cv2.imshow("Frame",frame)ifcv2.waitKey(1)==27:break

显示画面,按 ESC 退出。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/12 6:38:00

《艾尔登法环》世界观深度解析:从律法本质到结局逻辑的完整理论

1. 项目概述&#xff1a;一次对“交界地”的终极解构如果你和我一样&#xff0c;在《艾尔登法环》那浩瀚无垠、细节密布的交界地中探索了上百个小时&#xff0c;通关了数遍&#xff0c;却依然对某些剧情片段、人物动机乃至整个世界运行的底层逻辑感到困惑&#xff0c;那么这个项…

作者头像 李华
网站建设 2026/7/12 6:36:19

IntelliJ IDEA 2024.3.2 安装与激活:3种官方授权方案对比与避坑指南

IntelliJ IDEA 2024.3.2 官方授权方案全解析&#xff1a;学生/商业/开源项目三路径指南 作为Java开发者最信赖的集成开发环境&#xff0c;IntelliJ IDEA的专业版功能强大但授权方案常令人困惑。本文将系统梳理JetBrains官方提供的三种合规授权路径&#xff0c;帮助不同身份的用…

作者头像 李华
网站建设 2026/7/12 6:36:15

分层架构性能开销量化分析:3种通信模式对比与跨层优化策略

分层架构性能开销量化分析&#xff1a;3种通信模式对比与跨层优化策略在嵌入式系统开发中&#xff0c;分层架构设计已被广泛采用&#xff0c;但其性能开销问题却常被忽视。本文将深入探讨严格分层、松散分层和事件驱动三种层间通信模式的实际性能差异&#xff0c;并通过量化数据…

作者头像 李华
网站建设 2026/7/12 6:36:01

C语言实现RSA加密解密:从原理到OpenSSL实战指南

1. 项目概述&#xff1a;为什么C开发者需要掌握RSA&#xff1f;如果你是一名C语言开发者&#xff0c;无论是做嵌入式系统、服务器后端&#xff0c;还是安全相关的应用开发&#xff0c;迟早会遇到一个绕不开的坎&#xff1a;非对称加密。而RSA&#xff0c;作为非对称加密领域的“…

作者头像 李华
网站建设 2026/7/12 6:34:44

AI Agent代码生成约束实战:从失控到92%准确率的大厂方法论

1. 先搞清楚 AI Agent 代码生成为什么会“失控”AI Agent 代码生成最大的痛点不是功能不够强&#xff0c;而是生成结果不可控。你让 Agent 写一个数据查询接口&#xff0c;它可能给你返回三种不同风格的代码&#xff1a;有的用 MyBatis&#xff0c;有的用 JPA&#xff0c;还有的…

作者头像 李华