首页 > 其他分享 >dlib库实现摄像头疲劳检测(附源代码)

dlib库实现摄像头疲劳检测(附源代码)

时间:2024-06-17 16:29:49浏览次数:22  
标签:eye frame cv2 shape np array 源代码 dlib 摄像头

 

目录

1.导入库

2.定义添加中文文本的函数

3.定义绘制眼框凸包的函数

4.定义检测闭眼的函数

5.定义检测大笑的函数

6.构造检测器

7.计算纵横比

8.疲劳判定

9.可视化输出


  本代码将实现通过分析人脸的关键点进行疲劳检测,若持续闭眼则提示危险;考虑到大笑时也会眯眼,在同时检测到张嘴和眯眼时不做提醒。

1.导入库

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

2.定义添加中文文本的函数

def cv2AddChineseText (img, text, position, textColor=(0, 255,10), textSize=30):
    if (isinstance(img, np.ndarray)):  # 判断是否是OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 实现array到image的转换
    draw = ImageDraw.Draw(img)  # 在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)  # 转换为opencv

3.定义绘制眼框凸包的函数

def drawEye(eye) :#绘制眼框凸包
    eyeHull = cv2.convexHull(eye)
    cv2.drawContours(frame, [eyeHull], -1, (0, 255, 0), 1)

4.定义检测闭眼的函数

def eye_aspect_ratio(eye):  # 闭眼
    A = euclidean_distances(np.array(eye[1]), np.array(eye[5]))  #计算关键点间的欧氏距离
    B = euclidean_distances(np.array(eye[2]), np.array(eye[4]))
    C = euclidean_distances(np.array(eye[0]), np.array(eye[3]))
    ear = ((A + B) / 2.0) / C  # 眼部纵横比
    return ear

5.定义检测大笑的函数

def MAR(shape): # 计算嘴的宽高比
    A = euclidean_distances(np.array(shape[50]), np.array(shape[58]))
    B = euclidean_distances(np.array(shape[51]), np.array(shape[57]))
    C = euclidean_distances(np.array(shape[52]), np.array(shape[56]))
    D = euclidean_distances(np.array(shape[48]), np.array(shape[54]))
    return ((A + B + C) / 3) / D  # 嘴部纵向距离的平均值

6.构造检测器

COUNTER = 0 # 初始化一个计数器,用于后续跟踪连续检测到闭眼的帧数

detector = dlib.get_frontal_face_detector() #构造脸部位置检测器
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# 构造关键点检测器

7.计算纵横比

cap=cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    rects = detector(frame, 0)  # 检测所有人脸
    for rect in rects:
        shape = predictor(frame, rect)  # 获取每个人脸的关键点
        shape = np.matrix([[p.x, p.y] for p in shape.parts()])
        mar = MAR(shape)  # 计算嘴部的高宽比  大笑
        rightEye = shape[36:42]
        leftEye = shape[42:48]  # 左眼,关键点索引从42到47 (不包含48)
        rightEAR = eye_aspect_ratio(rightEye)  # 计算右眼纵横比
        leftEAR = eye_aspect_ratio(leftEye)  # 计算左眼纵横比
        ear = (leftEAR + rightEAR) / 2.0  # 左右眼均值处理

8.疲劳判定

        if ear < 0.3 and mar < 0.5:  # 小于0.3认为闭眼,也可能是眨眼
            COUNTER += 1  # 每检测到一次,计数器将+1
            if COUNTER >= 50:  # 持续50帧都闭眼,则警报
                frame = cv2AddChineseText(frame, "!!!!危险!!!!", (250, 250))

        elif ear < 0.3 and mar > 0.5:  # 可根据项目要求调整阈值  判定大笑
            frame = cv2AddChineseText(frame, "大笑", (250, 250))

        else:
            COUNTER = 0   # 宽高比>0.3,则计数器清零、解除疲劳标志

9.可视化输出

        drawEye(leftEye)  # 绘制左眼凸包
        drawEye(rightEye)  # 绘制右眼凸包

        info = "EAR: {:.2f}".format(ear[0][0])
        frame = cv2AddChineseText(frame, info, (0, 30))  # 显示眼睛闭合程度值
    cv2.imshow("Frame", frame)
    if cv2.waitKey(1) == 27:
        break
cv2.destroyAllWindows()
cap.release()

标签:eye,frame,cv2,shape,np,array,源代码,dlib,摄像头
From: https://blog.csdn.net/2301_77444219/article/details/139745741

相关文章