【Python 计算机视觉】基于 Dlib+OpenCV 实现实时人眼疲劳检测(闭眼预警)

目录

一、项目简介

二、算法原理

[1. 人脸 68 关键点](#1. 人脸 68 关键点)

[2. EAR 眼部纵横比公式](#2. EAR 眼部纵横比公式)

三、环境依赖

四、完整可运行代码

五、代码核心讲解

[1. EAR 计算函数](#1. EAR 计算函数)

[2. 中文绘制函数](#2. 中文绘制函数)

[3. 疲劳判定逻辑](#3. 疲劳判定逻辑)

六、常见报错解决

[1. 找不到 simsun.ttc 字体](#1. 找不到 simsun.ttc 字体)

[2. 找不到 shape_predictor_68_face_landmarks.dat](#2. 找不到 shape_predictor_68_face_landmarks.dat)

[3. 摄像头打不开](#3. 摄像头打不开)

七、效果展示

八、项目拓展


一、项目简介

本次使用 Dlib + OpenCV + 68 点人脸关键点 实现实时眼部疲劳检测 。 通过 EAR(Eye Aspect Ratio,眼睛纵横比) 判断眼睛开合状态,连续多帧闭眼则触发疲劳预警,可用于疲劳驾驶检测、工位离岗瞌睡检测、课堂状态监测等场景。

本方案无需训练深度学习模型,传统视觉算法实时性高、代码轻量化、电脑可直接跑。

二、算法原理

1. 人脸 68 关键点

Dlib 经典 68 个人脸关键点中:

  • 右眼:36--41
  • 左眼:42--47

2. EAR 眼部纵横比公式

通过眼睛上下眼睑关键点欧式距离计算眼睛开合程度:

  • A、B:眼睛垂直方向距离
  • C:眼睛水平宽度
  • EAR = (A+B)/2C

核心规律

  • 睁眼:EAR 数值较大
  • 闭眼 / 眯眼:EAR 急剧下降 常规阈值:EAR < 0.3 判定为闭眼

三、环境依赖

复制代码
pip install numpy opencv-python dlib pillow scikit-learn

额外准备: shape_predictor_68_face_landmarks.dat 关键点模型文件

四、完整可运行代码

python 复制代码
import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image,ImageFont,ImageDraw

# 计算EAR眼睛纵横比
def eye_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)/C
    return ear

# OpenCV绘制中文(解决乱码)
def cv2AddChineseText(img, text, position, textColor=(0, 255, 0), textSize=50):
    if isinstance(img, np.ndarray):
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    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)

# 绘制眼部轮廓
def drawEye(frame, 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()
    if not ret:
        break
    faces=detector(frame,0)
    for face in faces:
        shape=predictor(frame,face)
        shape=np.array([[p.x,p.y]for p in shape.parts()])
        # 截取左右眼关键点
        rightEye=shape[36:42]
        leftEye=shape[42:48]
        # 计算EAR
        rightEAR=eye_aspect_ratio(rightEye)
        leftEAR=eye_aspect_ratio(leftEye)
        ear=(leftEAR+rightEAR)/2.0

        # 连续闭眼判定疲劳
        if ear<0.3:
            COUNTER+=1
            if COUNTER>=50:
                frame=cv2AddChineseText(frame,"!!!危!!!",(250,250),textColor=(255,0,0))
        else:
            COUNTER=0

        # 绘制眼部轮廓
        drawEye(frame, leftEye)
        drawEye(frame, rightEye)
        # 显示实时EAR数值
        info="EAR:{:.2f}".format(ear[0][0])
        frame=cv2AddChineseText(frame,info,(0,30))

    cv2.imshow("Eye Fatigue Detect",frame)
    if cv2.waitKey(1)==27:
        break

cv2.destroyAllWindows()
cap.release()

五、代码核心讲解

1. EAR 计算函数

利用双眼 6 个特征点计算纵横比,精准反映眼睛开合状态,是整个疲劳检测的核心指标。

2. 中文绘制函数

原生 OpenCV 不支持中文,利用 PIL 进行图片转绘,完美解决中文乱码问题。

3. 疲劳判定逻辑

  • EAR 阈值 0.3:低于阈值判定闭眼
  • 连续 50 帧闭眼:触发疲劳警告 可根据帧率自行修改帧数阈值。

六、常见报错解决

1. 找不到 simsun.ttc 字体

报错:IOError: cannot open resource 解决:

  • Windows 自带宋体,直接运行即可
  • Linux/Mac 替换字体路径为系统已有字体

2. 找不到 shape_predictor_68_face_landmarks.dat

将模型文件放在代码同级目录即可。

3. 摄像头打不开

检查设备摄像头权限、设备是否被其他软件占用。

七、效果展示

  1. 正常睁眼:实时显示 EAR 数值,眼部绿色轮廓绘制
  2. 长时间闭眼:屏幕红色中文预警 !!!危!!!

八、项目拓展

  1. 增加眨眼计数统计
  2. 增加打哈欠嘴巴检测
  3. 接入视频文件检测,不止实时摄像头
  4. 增加报警音效、弹窗提醒
相关推荐
嘘嘘出差2 小时前
Python 爬虫入门实战:爬取豆瓣电影 Top 250
开发语言·爬虫·python
爱写代码的倒霉蛋2 小时前
实现协程的三种方式
开发语言·python
崖边看雾3 小时前
记录Python学习——第一章环境安装下载(Windows)
windows·python·学习·pycharm
用户298698530143 小时前
Python 实现 Excel 到 ODS、XPS、PostScript 及 PDF/A-1b 的格式转换
后端·python·excel
本地化文档3 小时前
xlwings-docs-l10n
python·github·excel·gitcode·sphinx
梅雅达编程笔记4 小时前
零基础学 Python 第7章 | 字典 dict:键值对存储
开发语言·python·beautifulsoup·numpy·pandas
heroboyluck4 小时前
AI工程师第四课 - 深度学习入门
人工智能·python·深度学习·llama
alicema11114 小时前
BRAIN 研究顾问(Research Consultant)兼职
python·量化