当前位置: 首页 > news >正文

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

目录

一.dlib库关键点定位

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

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

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

二.关键点轮廓绘制

三.疲劳检测

1.疲劳检测技术与原理

2.代码实现要点

①数据处理,计算纵横比

②基本处理

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

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

⑤防误报机制

⑥显示

⑦释放资源


一.dlib库关键点定位

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

import numpy as np
import cv2
import dlibimg=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()

二.关键点轮廓绘制

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

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函数,根据步骤二中提取到的两个坐标点作为起点和终点,绘制一条线段。

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)的函数,它可以从一组点集中找到能包含所有点的 最小凸多边形。这个概念源自计算几何,"凸" 意味着多边形内部任意两点的连线都完全在多边形内部,不存在凹陷。

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

其余代码:

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模块,高效地计算关键点之间的欧式距离。

  • 数据维度注意:在调用距离计算函数时,需要注意传入参数必须为二维数组,因此在传参前需通过括号处理。
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用于连续帧检测

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()])

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

        rightEye=shape[36:42]leftEye=shape[42:48]

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

        rightEar=eye_aspect_ratio(rightEye)leftEar=eye_aspect_ratio(leftEye)ear=(leftEar+rightEar)/2.0

⑤防误报机制

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

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

⑥显示

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)
        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

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

⑦释放资源

video.release()
cv2.destroyAllWindows()

http://www.dtcms.com/a/409884.html

相关文章:

  • 甘肃省建设工程网上投标网站学院门户网站建设
  • JavaWeb--day11--登录认证
  • [VCS]Verdi/VCS 波形调试最佳实践清单
  • 网站怎么做播放窗口网站数据模版
  • 深入理解Kafka的复制协议与可靠性保证
  • 自动化接口框架搭建分享-pytest第三部分
  • WPF 控件悬停弹窗高级指南:用 Behavior 实现带动画的智能 HoverPopup
  • 佳维视工业显示器在喷码机中的应用
  • 自存19-48
  • ARM CoreSight:多核SoC调试追踪架构解析
  • Windows 显示器EDID笔记
  • 有哪些做任务的网站海淀区seo搜索引擎优化企业
  • 【C++实战㊻】解锁C++观察者模式:从理论到实战
  • 类和对象(二)
  • 开源多场景问答社区论坛Apache Answer本地部署并发布至公网使用
  • vue3 通过 Vue3DraggableResizable实现拖拽弹窗,可修改大小
  • 广州网站制作信科建设白名单 网站
  • DirBuster工具的文本介绍以及使用方法
  • DeepSeek-V3.1-Terminus:蓝耘API+CherryStudio实测国产最新开源模型,推理能力竟让我后背发凉
  • 金仓数据库:破解电子证照国产化难题,开启政务效能新篇
  • 杭州小蜜蜂网站建设宝坻做网站哪家好
  • 解析前端框架 Axios 的设计理念与源码:从 Promise 美学到双适配架构
  • MQTT 关键特性详解
  • 数据仓库与数据挖掘课程设计
  • 半导体数据分析:GPR算法小白入门(三) 晶体管I-V特性仿真教程
  • 深入理解 Qt 元对象系统:QMetaEnum 的应用与实践
  • html video标签mp4格式视频显示不出来的问题
  • Unity 虚拟仿真实验中设计模式的使用 ——策略模式(Strategy Pattern)
  • 企业级网站欣赏新乡个人网站建设
  • 设计模式——单例模式