辅助驾驶技术——基于mediapipe的驾驶人睡意检测
ztj100 2024-10-30 05:12 25 浏览 0 评论
什么是MediaPipe
MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。在谷歌,一系列重要产品,如 、Google Lens、ARCore、Google Home 以及 ,都已深度整合了 MediaPipe。
MediaPipe 的核心框架由 C++ 实现,并提供 Java 以及 Objective C 等语言的支持。MediaPipe 的主要概念包括数据包(Packet)、数据流(Stream)、计算单元(Calculator)、图(Graph)以及子图(Subgraph)。
MediaPipe不仅可以进行人体姿态检测,手势识别,人脸检测与识别外,还可以进行3D物体对象检测等等,本期我们就基于MediaPipe的人脸检测来进行驾驶人的睡意检测。
MediaPipe Face Mesh
MediaPipe Face Mesh是一种脸部几何解决方案,即使在移动设备上,也可以实时估计468个3D脸部界标(dlib才能检测出68点)。它采用机器学习(ML)来推断3D表面几何形状,只需要单个摄像机输入,而无需专用的深度传感器。该解决方案利用轻量级的模型架构以及整个管线中的GPU加速,可提供对实时体验至关重要的实时性能。我们要进行驾驶人睡意检测,需要使用到MediaPipe Face Mesh 468个人脸关键点的人眼睛部分。眼部区域有32个点(每个眼睛有16个)。 为了计算眼睛的坐标,我们只需要 12 个点(每只眼睛 6 个)。
选择的12个点如下:
左眼:[362, 385, 387, 263, 373, 380]
右眼:[33, 160, 158, 133, 153, 144]
点坐标依次为:P1, P2, P3, P4, P5, P6
驾驶人睡意检测理论
为了检测人眼的闭合状态,我们使用眼睛纵横比比(EAR)公式:
前期我们也使用过opencv来进行人眼的睡意检测,可以参考往期内容
按照我们的目标要求,我们需要进行驾驶人睡意检测,当然我们要从视频流中来实时检测,本期我们先按照检测图片的步骤先把此流程过一遍
1、我们输入一张人脸图片
2、mediapipe来进行人脸的468点的检测
3、从468点中获取人眼检测部分的12个点
4、根据EAR计算公式来计算人眼间的距离
5、根据计算的距离值与设置值进行对比
6、获取驾驶人睡意检测概率,进行提醒操作
mediapipe驾驶人睡意检测代码实现
import cv2
import numpy as np
import matplotlib.pyplot as plt
import mediapipe as mp
mp_facemesh = mp.solutions.face_mesh
mp_drawing = mp.solutions.drawing_utils
denormalize_coordinates = mp_drawing._normalized_to_pixel_coordinates
all_left_eye_idxs = list(mp_facemesh.FACEMESH_LEFT_EYE)
all_left_eye_idxs = set(np.ravel(all_left_eye_idxs))
all_right_eye_idxs = list(mp_facemesh.FACEMESH_RIGHT_EYE)
all_right_eye_idxs = set(np.ravel(all_right_eye_idxs))
all_idxs = all_left_eye_idxs.union(all_right_eye_idxs)
chosen_left_eye_idxs = [362, 385, 387, 263, 373, 380]
chosen_right_eye_idxs = [33, 160, 158, 133, 153, 144]
all_chosen_idxs = chosen_left_eye_idxs + chosen_right_eye_idxs
image_int = cv2.imread(r"2.png")
image = cv2.cvtColor(image_int, cv2.COLOR_BGR2RGB)
image = np.ascontiguousarray(image)
imgH, imgW, _ = image.shape
cv2.imshow('image',image_int)
cv2.waitKey(0)
首先,我们import mediapipe第三方包,以便使用mediapipe来进行人脸的468点的检测,并获取左右眼睛的32点坐标点,我们从32个坐标点中获取12个坐标点,左右眼睛各6个。然后我们加载一张需要检测的照片,方便后期进行图片的人脸468点检测。当然关于mediapipe的详细介绍,可以参考文章末尾的扩展阅读。
with mp_facemesh.FaceMesh(
static_image_mode=True, # Default=False
max_num_faces=1, # Default=1
refine_landmarks=False,
min_detection_confidence=0.5, # Default=0.5
min_tracking_confidence= 0.5, # Default=0.5
) as face_mesh:
results = face_mesh.process(image)
我们直接使用mp_facemesh.FaceMesh中的process函数进行图片的人脸468点检测,经过此函数后,我们就得到了468个坐标点,我们需要从这468点中得到左右眼睛的12个点。其结果保存在results中。
def plot_pic(
*,
img_dt,
img_eye_lmks=None,
img_eye_lmks_chosen=None,
face_landmarks=None,
ts_thickness=1,
ts_circle_radius=2,
lmk_circle_radius=3,
name="1",
):
image_drawing_tool = img_dt
image_eye_lmks = img_dt.copy() if img_eye_lmks is None else img_eye_lmks
img_eye_lmks_chosen = img_dt.copy() if img_eye_lmks_chosen is None else img_eye_lmks_chosen
connections_drawing_spec = mp_drawing.DrawingSpec(
thickness=ts_thickness,
circle_radius=ts_circle_radius,
color=(255, 255, 255)
)
mp_drawing.draw_landmarks(
image=image_drawing_tool,
landmark_list=face_landmarks,
connections=mp_facemesh.FACEMESH_TESSELATION,
landmark_drawing_spec=None,
connection_drawing_spec=connections_drawing_spec,
)
landmarks = face_landmarks.landmark
for landmark_idx, landmark in enumerate(landmarks):
if landmark_idx in all_idxs:
pred_cord = denormalize_coordinates(landmark.x, landmark.y, imgW, imgH)
cv2.circle(image_eye_lmks, pred_cord, lmk_circle_radius, (255, 255, 255), -1 )
if landmark_idx in all_chosen_idxs:
pred_cord = denormalize_coordinates(landmark.x, landmark.y, imgW, imgH)
cv2.circle(img_eye_lmks_chosen, pred_cord, lmk_circle_radius, (255, 255, 255), -1 )
imghstack = np.hstack((img_eye_lmks_chosen, image_eye_lmks,image_drawing_tool))
cv2.imshow('imghstack',imghstack)
cv2.waitKey(0)
为了方便,我们建立一个plot_pic函数来从人脸468个关键点中获取12个左右眼睛的关键点
if results.multi_face_landmarks:
for face_id, face_landmarks in enumerate(results.multi_face_landmarks):
_ = plot_pic(img_dt=image.copy(), face_landmarks=face_landmarks)
得到12个关键点后,我们便可以利用EAR公式来计算驾驶人睡意检测的概率了
image_eyes_open = cv2.imread("3.png")[:, :, ::-1]
for idx, image in enumerate([image_eyes_open]):
image = np.ascontiguousarray(image)
imgH, imgW, _ = image.shape
custom_chosen_lmk_image = image.copy()
with mp_facemesh.FaceMesh(refine_landmarks=True) as face_mesh:
results = face_mesh.process(image).multi_face_landmarks
if results:
for face_id, face_landmarks in enumerate(results):
landmarks = face_landmarks.landmark
EAR, _ = calculate_avg_ear( landmarks, chosen_left_eye_idxs, chosen_right_eye_idxs, imgW, imgH)
cv2.putText(custom_chosen_lmk_image, f"EAR: {round(EAR, 2)}", (1, 24), cv2.FONT_HERSHEY_COMPLEX, 0.9, (255, 255, 255), 2)
plot(img_dt=image.copy(),img_eye_lmks_chosen=custom_chosen_lmk_image, face_landmarks=face_landmarks,ts_thickness=1, ts_circle_radius=3, lmk_circle_radius=3 )
可以看到,当人眼闭合时,根据EAR的计算公式,其值就会很小,当人眼睁开时,其值就会变大。
当然,我们可以多收集一些数据,计算一个人眼睁开与闭合的数据,通过多个数据,计算一个比较合适的阈值,通过此阈值,我们检测到的人眼尺寸与此阈值来做对比,以便进行驾驶人的睡意检测。
我们真正利用此技术来应用到辅助驾驶汽车上时,我们需要从汽车摄像头上实时获取视频流,以便对视频流中的人脸进行睡意检测,当然,我们检测到驾驶员有睡意情况时,我们需要进行相关的提醒。本期我们介绍了如何使用mediapipe来进行驾驶员睡意检测,但是我们只是进行了一张图片的检测,且真实情况下,人会不停的眨眼睛,因此,我们还需要进行时间的判断,超过多少时间的眼睛闭合才真正算是驾驶员有睡意,我们后期再进行详细的分享。
扩展阅读:
毫秒级人体姿态检测模型MediaPipe,这速度,还能有那个模型比拟
MediaPipe 集成人脸识别,人体姿态评估,人手检测模型
相关推荐
- 再说圆的面积-蒙特卡洛(蒙特卡洛方法求圆周率的matlab程序)
-
在微积分-圆的面积和周长(1)介绍微积分方法求解圆的面积,本文使用蒙特卡洛方法求解圆面积。...
- python创建分类器小结(pytorch分类数据集创建)
-
简介:分类是指利用数据的特性将其分成若干类型的过程。监督学习分类器就是用带标记的训练数据建立一个模型,然后对未知数据进行分类。...
- matplotlib——绘制散点图(matplotlib散点图颜色和图例)
-
绘制散点图不同条件(维度)之间的内在关联关系观察数据的离散聚合程度...
- python实现实时绘制数据(python如何绘制)
-
方法一importmatplotlib.pyplotaspltimportnumpyasnpimporttimefrommathimport*plt.ion()#...
- 简单学Python——matplotlib库3——绘制散点图
-
前面我们学习了用matplotlib绘制折线图,今天我们学习绘制散点图。其实简单的散点图与折线图的语法基本相同,只是作图函数由plot()变成了scatter()。下面就绘制一个散点图:import...
- 数据分析-相关性分析可视化(相关性分析数据处理)
-
前面介绍了相关性分析的原理、流程和常用的皮尔逊相关系数和斯皮尔曼相关系数,具体可以参考...
- 免费Python机器学习课程一:线性回归算法
-
学习线性回归的概念并从头开始在python中开发完整的线性回归算法最基本的机器学习算法必须是具有单个变量的线性回归算法。如今,可用的高级机器学习算法,库和技术如此之多,以至于线性回归似乎并不重要。但是...
- 用Python进行机器学习(2)之逻辑回归
-
前面介绍了线性回归,本次介绍的是逻辑回归。逻辑回归虽然名字里面带有“回归”两个字,但是它是一种分类算法,通常用于解决二分类问题,比如某个邮件是否是广告邮件,比如某个评价是否为正向的评价。逻辑回归也可以...
- 【Python机器学习系列】拟合和回归傻傻分不清?一文带你彻底搞懂
-
一、拟合和回归的区别拟合...
- 推荐2个十分好用的pandas数据探索分析神器
-
作者:俊欣来源:关于数据分析与可视化...
- 向量数据库:解锁大模型记忆的关键!选型指南+实战案例全解析
-
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...
- 用Python进行机器学习(11)-主成分分析PCA
-
我们在机器学习中有时候需要处理很多个参数,但是这些参数有时候彼此之间是有着各种关系的,这个时候我们就会想:是否可以找到一种方式来降低参数的个数呢?这就是今天我们要介绍的主成分分析,英文是Princip...
- 神经网络基础深度解析:从感知机到反向传播
-
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在...
- Python实现基于机器学习的RFM模型
-
CDA数据分析师出品作者:CDALevelⅠ持证人岗位:数据分析师行业:大数据...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)