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

完整教程: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()

二.关键点轮廓绘制

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

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.rkmt.cn/news/13475.html

相关文章:

  • VKD233HH触控IC有两种输出方式“直接输出”和“锁存输出”单路触摸检测芯片
  • C# Avalonia 15- Animation- CachingTest
  • Ansible + Docker 部署 MinIO 集群
  • 自动遍历测试利器:开源工具AppCrawler 配置全解析
  • 250928
  • window 安全模式卸载任何软件
  • 定制笔记本电脑工厂排名:从基础代工到联合设计全面分析 - 教程
  • sv 去除字符串行尾空格函数
  • linux执行yum报错: except KeyboardInterrrupt, e
  • grafana如何添加自定义geoJson地图
  • AI元人文:追问与悟空
  • 2025 年纽扣电池厂家:力源电池以 TWS 适配技术与定制服务,打造多场景电源解决方案
  • AWS SageMaker SDK 完整教程:从零开始云端训练你的模型
  • 反转数字-处理溢出的条件-Java
  • Storm-0501威胁组织利用云技术实施勒索攻击的技术分析
  • US$289 VVDI2 AUDI and 5th IMMO Functions Authorization Service
  • OpenLayers地图交互 -- 章节十三:拖拽旋转交互详解 - 实践
  • Python抖音直播间实时数据获取方案:弹幕、礼物与互动消息全解析 - 教程
  • Gitee企业版MCP Server:开启AI驱动的企业研发新时代
  • kafka-日志收集高效的平台部署任务
  • iOS Xcode16 中删除描述文件 Provisioning Profiles
  • git仓库管理memo
  • 关键领域软件研发知识管理的范式革命:从静态文档到智能图谱的跃迁
  • Discord桌面应用远程代码执行漏洞分析
  • DRL模型训练:原始奖励函数记录以及绘制
  • 【Boolean】布尔值:逻辑判断的基础
  • Modbus RTU TCP 拓扑
  • 借助Aspose.Email,使用 Python 将 EML 转换为 MHTML
  • python+springboot+django/flask的医院食堂订餐系统 菜单发布 在线订餐 餐品管理与订单统计系统 - 教程
  • 计算机网络学习笔记 - 浪矢