dlib库关键点定位和疲劳检测

目录

一.dlib库关键点定位

1.创建检测器并检测人脸

2.加载检测人脸68关键点文件

3.循环处理每一个人脸信息

二.关键点轮廓绘制

三.疲劳检测

1.疲劳检测技术与原理

2.代码实现要点

①数据处理,计算纵横比

②基本处理

③获取左眼和右眼的坐标信息列表

④调用方法计算左眼和右眼的纵横比和平均纵横比

⑤防误报机制

⑥显示

⑦释放资源


一.dlib库关键点定位

1.创建检测器并检测人脸

复制代码
import numpy as np
import cv2
import dlib

img=cv2.imread('img.png')
img = cv2.resize(img, (400, 700))
detector=dlib.get_frontal_face_detector()
faces=detector(img,0)

2.加载检测人脸68关键点文件

GitHub - davisking/dlib-models: Trained model files for dlib example programs.

复制代码
shape_predictor_68_face_landmarks.dat文件提前从该网址下载
复制代码
predictor=dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')

3.循环处理每一个人脸信息

复制代码
for face in faces:
    shape=predictor(img,face)
    landmarks=np.array([[p.x,p.y] for p in shape.parts()])
    for idx,point in enumerate(landmarks):
        pos=[point[0],point[1]]
        cv2.circle(img,pos,2,(0,255,0),-1)
        cv2.putText(img,str(idx),pos,cv2.FONT_HERSHEY_SIMPLEX,0.4,(255,255,255),1,cv2.LINE_AA)
cv2.imshow('img',img)
cv2.waitkey(0)

先通过predictor(img,face)获取68个关键点的信息

再将其中的坐标信息用矩阵保存

遍历矩阵在img上标出关键点小圆和序号

复制代码
cv2.destroyAllWindows()

二.关键点轮廓绘制

大致与上述代码相同,不同是定义了两个方法

python 复制代码
def drawLine(start,end):
    pts=shape[start:end]
    for l in range(1,len(pts)):
        ptA=tuple(pts[l-1])
        ptB=tuple(pts[l])
        cv2.line(image,ptA,ptB,(0,255,0),2)
复制代码
例如drawLine(0,17)

通过切片操作,从完整的坐标列表中筛选出特定区域(如从第0到17点可以参考上图)的坐标数据PTS

使用for循环遍历筛选后的坐标数据,每次循环将连续的两个坐标点提取出来。

调用drawLine函数,根据步骤二中提取到的两个坐标点作为起点和终点,绘制一条线段。

python 复制代码
def drawConvexHull(start,end):
    Facial=shape[start:end+1]
    mouthHull=cv2.convexHull(Facial)
    cv2.drawContours(image,[mouthHull],-1,(0,255,0),2)
复制代码
例如drawConvexHull(36,41)

提取第36个到第41个关键点坐标

cv2.convexHull() 是 OpenCV 中用于计算凸包(Convex Hull)的函数,它可以从一组点集中找到能包含所有点的 最小凸多边形。这个概念源自计算几何,"凸" 意味着多边形内部任意两点的连线都完全在多边形内部,不存在凹陷。

最后将连接后的凸多边形当作轮廓画出

其余代码:

python 复制代码
import numpy as np
import dlib
import cv2
image=cv2.imread('img.png')
image = cv2.resize(image, (400, 700))
detector=dlib.get_frontal_face_detector()
faces=detector(image,0)
predictor=dlib.shape_predictor('../关键点定位/shape_predictor_68_face_landmarks.dat')
for face in faces:
    shape=predictor(image,face)
    shape=np.array([[p.x,p.y] for p in shape.parts()])
    drawConvexHull(36,41)
    drawConvexHull(42,47)
    drawConvexHull(48,59)
    drawConvexHull(60,67)

    drawLine(0,17)
    drawLine(17,22)
    drawLine(22,27)
    drawLine(27,36)
cv2.imshow('Frame',image)
cv2.waitKey(0)
cv2.destroyAllWindows()

三.疲劳检测

1.疲劳检测技术与原理

  • 核心思路:通过检测和分析人脸上的68个关键点,特别是眼睛区域的6个关键点,来判断用户是否处于疲劳状态。
  • 核心指标:采用"眼睛横纵比"作为判断依据。此比值是通过计算竖直方向上两点间的距离(e.g., 点37到41和点38到40的平均值),除以水平方向的距离(e.g., 点36到41)得出。
  • 判断阈值
    • 当比值大于0.3,表示眼睛正常睁开。
    • 当比值小于等于0.3,表明可能处于闭合或疲劳状态。系统通过连续帧的监测来避免误报,例如连续50帧均低于0.3才会触发报警。

2.代码实现要点

①数据处理,计算纵横比

利用OpenCV的distance模块,高效地计算关键点之间的欧式距离。

  • 数据维度注意:在调用距离计算函数时,需要注意传入参数必须为二维数组,因此在传参前需通过括号处理。
python 复制代码
from sklearn.metrics.pairwise import euclidean_distances
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)/C#纵横比
    return ear

②基本处理

COUNNTER用于连续帧检测

python 复制代码
COUNTER=0
video=cv2.VideoCapture(0)
detector=dlib.get_frontal_face_detector()
predictor=dlib.shape_predictor('../关键点定位/shape_predictor_68_face_landmarks.dat')
while True:
    ret,frame=video.read()
    faces = detector(frame, 0)
    for face in faces:
        shape=predictor(frame,face)
        shape=np.array([[p.x,p.y] for p in shape.parts()])

③获取左眼和右眼的坐标信息列表

python 复制代码
        rightEye=shape[36:42]
        leftEye=shape[42:48]

④调用方法计算左眼和右眼的纵横比和平均纵横比

python 复制代码
        rightEar=eye_aspect_ratio(rightEye)
        leftEar=eye_aspect_ratio(leftEye)
        ear=(leftEar+rightEar)/2.0

⑤防误报机制

python 复制代码
        if ear<0.3:
            COUNTER+=1
            if COUNTER>=50:
                frame=cv2_put_text_cn(frame,'!!!!危险!!!!',(250,250))
        else:
            COUNTER=0

设计了counter计数器,仅当单片帧信息低于阈值时计数加1;一旦遇到高于阈值的帧,将立即将计数器重置为0,确保报警的严谨性

⑥显示

python 复制代码
def drawEye(eye):
    eyeHUll=cv2.convexHull(eye)
    cv2.drawContours(frame,[eyeHUll],-1,(0,255,0),-1)
def cv2_put_text_cn(img, text, org, font_size=20, color=(0, 255, 0)):
    """
    在OpenCV图像上绘制中文

    参数:
        img: OpenCV图像(numpy数组)
        text: 要绘制的中文文本
        org: 文本起始位置(x, y)
        font_size: 字体大小
        color: 文本颜色,BGR格式
    返回:
        绘制了文本的图像
    """
    # 转换OpenCV图像为PIL图像
    img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    # 创建绘制对象
    draw = ImageDraw.Draw(img_pil)

    # 加载中文字体,这里使用系统中的宋体
    # 注意:需要根据自己系统的字体路径进行调整
    try:
        # Windows系统常见字体路径
        font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", font_size, encoding="utf-8")
    except:
        try:
            # Linux系统常见字体路径
            font = ImageFont.truetype("/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc", font_size)
        except:
            # Mac系统常见字体路径
            font = ImageFont.truetype("/System/Library/Fonts/PingFang.ttc", font_size)

    # 绘制中文
    draw.text(org, text, font=font, fill=(color[2], color[1], color[0]))

    # 转换回OpenCV格式
    return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
python 复制代码
        drawEye(leftEye)
        drawEye(rightEye)
        info="EAR: {:.2f}".format(ear[0][0])
        frame=cv2_put_text_cn(frame,info,(0,30))
    cv2.imshow('frame',frame)
    if cv2.waitKey(1)==27:
        break

会在原视频画面中,用绿色填充检测出的特征点轮廓,并在左上角实时显示当前计算的平均横纵比数值。

⑦释放资源

python 复制代码
video.release()
cv2.destroyAllWindows()
相关推荐
汀丶人工智能2 小时前
AI Compass前沿速览:Qwen3-Max、Mixboard、Qwen3-VL、Audio2Face、Vidu Q2 AI视频生成模型、Qwen3-Liv
人工智能
唐天下文化2 小时前
展厅迎宾机器人:豹小秘2如何打造科技第一印象
人工智能·科技·机器人
qiu_zhongya3 小时前
iree 用C++来运行Qwen 2.5 0.5b
开发语言·c++·人工智能
拾贰_C3 小时前
【anaconda】anaconda安装配置,git安装配置以及pytorch安装
人工智能·pytorch·git
荼蘼3 小时前
Dlib+OpenCV 人脸轮廓绘制
人工智能·opencv·计算机视觉
九河云3 小时前
物流仓储自动化升级:物道供应链 AGV 机器人实现分拣效率提升 60%
人工智能·科技·物联网·机器人·自动化
正点原子3 小时前
正点原子 x STM32:智能加速边缘AI应用开发!
人工智能·stm32·嵌入式硬件
金井PRATHAMA3 小时前
GraphRAG(知识图谱结合大模型)对人工智能中自然语言处理的深层语义分析的影响与启示
人工智能·自然语言处理·知识图谱
CCSBRIDGE4 小时前
Browser-Use 的实现原理
人工智能