【深度学习实战—9】:基于MediaPipe的坐姿检测

✨博客主页:王乐予🎈
✨年轻人要:Living for the moment(活在当下)!💪
🏆推荐专栏:【图像处理】【千锤百炼Python】【深度学习】【排序算法】

目录

  • 😺一、MediaPipe概述
  • 😺二、MediaPipe姿态特征点检测
    • 🐶2.1 概述
    • 🐶2.2 度量函数
  • 😺三、代码实现
    • 🐶3.1 utils.py
    • 🐶3.2 main.py
  • 😺四、参考

😺一、MediaPipe概述

MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。

MediaPipe目前支持的解决方案(Solution)及支持的平台如下图所示:
在这里插入图片描述

😺二、MediaPipe姿态特征点检测

🐶2.1 概述

通过 MediaPipe Pose Marker,可以检测图片或视频中人体的特征点。使用此任务识别关键的身体位置,分析姿势并对动作进行分类。该任务会在图片坐标和三维世界坐标中输出身体姿势地标。

姿势特征点使用一系列模型来预测姿势特征点。第一个模型检测图片帧中是否存在人体,第二个模型则在身体上定位地标。

姿势特征点模型会跟踪 33 个身体特征点位置,表示以下身体部位的大致位置:
请添加图片描述
点位信息如下:

0 - nose
1 - left eye (inner)
2 - left eye
3 - left eye (outer)
4 - right eye (inner)
5 - right eye
6 - right eye (outer)
7 - left ear
8 - right ear
9 - mouth (left)
10 - mouth (right)
11 - left shoulder
12 - right shoulder
13 - left elbow
14 - right elbow
15 - left wrist
16 - right wrist
17 - left pinky
18 - right pinky
19 - left index
20 - right index
21 - left thumb
22 - right thumb
23 - left hip
24 - right hip
25 - left knee
26 - right knee
27 - left ankle
28 - right ankle
29 - left heel
30 - right heel
31 - left foot index
32 - right foot index

🐶2.2 度量函数

坐姿检测将使用不同关键点的向量夹角做判定,向量内角图如下:
在这里插入图片描述
内角计算与向量的起止顺序有关,在上图中,假定选择kpt1和kpt2为人体的两个关键点,kpt3为向量起始点即kpt1的垂直方向任意位置的点,则夹角为:
θ = arccos ⁡ ( P 12 → × P 13 → ∣ P 12 → ∣ ∣ P 13 → ∣ ) \theta =\arccos (\frac{\overrightarrow{P_{12} } \times \overrightarrow{P_{13} } }{\left | \overrightarrow{P_{12} } \right | \left | \overrightarrow{P_{13} } \right | } ) θ=arccos( P12 P13 P12 ×P13 )

不妨设kpt3的y3坐标为0,则带入坐标值有:
θ = arccos ⁡ ( y 1 2 − y 1 × y 2 y 1 ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 ) \theta =\arccos (\frac{y_{1}^{2} - y_{1}\times y_{2} }{y_{1}\sqrt{(x_{2}-x_{1})^{2}+(y_{2}-y_{1})^{2} } } ) θ=arccos(y1(x2x1)2+(y2y1)2 y12y1×y2)

根据上图可知 θ \theta θ为锐角,如果向量方向为由kpt2指向kpt1,则需要在kpt2的垂直方向标记点kpt3,此时 θ \theta θ为钝角。

😺三、代码实现

  • utils.py:包含度量函数的定义与姿态检测函数
  • main.py:主函数,获取需要的关键点数据,绘图

🐶3.1 utils.py

import math as m# 度量函数
def findAngle(x1, y1, x2, y2):theta = m.acos((y2 - y1) * (-y1) / (m.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2) * y1))degree = int(180/m.pi)*thetareturn degree"""
歪头监控:计算 左耳(7点)和 右耳(8点)的夹角
低头监控:计算 左嘴角(9点)和 左肩膀(11点)的夹角
侧脸监控:计算 右眼内(4点)和 左耳(7点)的距离,计算 左眼内(1点)和 右耳(8点)的距离
高低肩监控:计算 左肩膀(11点)和 右肩膀(12点)的夹角            *****有的人左肩和右肩一个高一个低*****
撑桌监控:如果 左嘴角(9点)或者 右嘴角(10点)的 y 坐标 大于 左肩膀(11点)或 右肩膀(12点)的 y 坐标,视为撑桌
仰头监控:计算 鼻子(0点)和 左耳(7点)的夹角
趴桌监控:如果 左肩膀(11点)和 右肩膀(12点)的 归一化y坐标 之和大于0.75,判定为趴桌
"""
def all_detection(nose_x, nose_y,                               # 鼻子(0点)的 x 坐标 和 y 坐标left_eye_inner_x, left_eye_inner_y,           # 左眼内(1点)的 x 坐标 和 y 坐标right_eye_inner_x, right_eye_inner_y,         # 右眼内(4点)的 x 坐标 和 y 坐标left_ear_x, left_ear_y,                       # 左耳(7点)的 x 坐标 和 y 坐标right_ear_x, right_ear_y,                     # 右耳(8点)的 x 坐标 和 y 坐标left_mouth_x, left_mouth_y,                   # 左嘴角(9点)的 x 坐标 和 y 坐标right_mouth_x, right_mouth_y,                 # 右嘴角(10点)的 x 坐标 和 y 坐标left_shoulder_x, left_shoulder_y,             # 左肩膀(11点)的 x 坐标 和 y 坐标right_shoulder_x, right_shoulder_y,           # 右肩膀(12点)的 x 坐标 和 y 坐标left_shoulder_x_norm, left_shoulder_y_norm,   # 归一化后的左肩膀(11点)的 x 坐标 和 y 坐标right_shoulder_x_norm, right_shoulder_y_norm  # 归一化后的右肩膀(12点)的 x 坐标 和 y 坐标):waitou_inclination = findAngle(left_ear_x, left_ear_y, right_ear_x, right_ear_y)ditou_inclination = findAngle(left_mouth_x, left_mouth_y, left_shoulder_x, left_shoulder_y)gaodijian_inclination = findAngle(left_shoulder_x, left_shoulder_y, right_shoulder_x, right_shoulder_y)yangtou_inclination = findAngle(nose_x, nose_y, left_ear_x, left_ear_y)if waitou_inclination < 80:tmp = '左歪头'elif waitou_inclination > 100:tmp = '右歪头'elif (left_shoulder_y_norm + right_shoulder_y_norm) > 1.5:tmp = '趴桌'elif ditou_inclination < 115:tmp = '低头'elif left_ear_x < right_eye_inner_x:tmp = '左侧脸'elif right_ear_x > left_eye_inner_x:tmp = '右侧脸'elif gaodijian_inclination > 100:tmp = '高低肩'elif gaodijian_inclination < 80:tmp = '高低肩'elif (left_mouth_y or right_mouth_y) > (left_shoulder_y or right_shoulder_y):tmp = '撑桌'elif yangtou_inclination > 90:tmp = '仰头'else:tmp = '正脸'return tmp

🐶3.2 main.py

import cv2
import mediapipe as mp
from utils import *mp_pose = mp.solutions.pose
pose = mp_pose.Pose(model_complexity=1, min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utilscap = cv2.VideoCapture(0)while True:ret, frame = cap.read()h, w = frame.shape[:2]image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)keypoints = pose.process(image)image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)lm = keypoints.pose_landmarkslmPose = mp_pose.PoseLandmark# 歪头监控left_ear_x = int(lm.landmark[lmPose.LEFT_EAR].x * w)    # 左耳(7点)x 坐标left_ear_y = int(lm.landmark[lmPose.LEFT_EAR].y * h)    # 左耳(7点)y 坐标right_ear_x = int(lm.landmark[lmPose.RIGHT_EAR].x * w)  # 右耳(8点)x 坐标right_ear_y = int(lm.landmark[lmPose.RIGHT_EAR].y * h)  # 右耳(8点)y 坐标# 低头监控left_mouth_x = int(lm.landmark[lmPose.MOUTH_LEFT].x * w)    # 左嘴角(9点)x 坐标left_mouth_y = int(lm.landmark[lmPose.MOUTH_LEFT].y * h)    # 左嘴角(9点)y 坐标left_shoulder_x = int(lm.landmark[lmPose.LEFT_SHOULDER].x * w)    # 左肩膀(11点)x 坐标left_shoulder_y = int(lm.landmark[lmPose.LEFT_SHOULDER].y * h)    # 左肩膀(11点)y 坐标# 侧脸监控left_eye_inner_x = int(lm.landmark[lmPose.LEFT_EYE_INNER].x * w)    # 左眼内(1点)x 坐标left_eye_inner_y = int(lm.landmark[lmPose.LEFT_EYE_INNER].y * h)    # 左眼内(1点)y 坐标right_eye_inner_x = int(lm.landmark[lmPose.RIGHT_EYE_INNER].x * w)  # 右眼内(4点)x 坐标right_eye_inner_y = int(lm.landmark[lmPose.RIGHT_EYE_INNER].y * h)  # 右眼内(4点)y 坐标# 高低肩监控right_shoulder_x = int(lm.landmark[lmPose.RIGHT_SHOULDER].x * w)  # 右肩膀(12点)x 坐标right_shoulder_y = int(lm.landmark[lmPose.RIGHT_SHOULDER].y * h)  # 右肩膀(12点)y 坐标# 撑桌监控right_mouth_x = int(lm.landmark[lmPose.MOUTH_RIGHT].x * w)  # 左嘴角(10点)x 坐标right_mouth_y = int(lm.landmark[lmPose.MOUTH_RIGHT].y * h)  # 左嘴角(10点)y 坐标# 仰头监控nose_x = int(lm.landmark[lmPose.NOSE].x * w)    # 鼻子(0点)x 坐标nose_y = int(lm.landmark[lmPose.NOSE].y * h)    # 鼻子(0点)y 坐标# 趴桌监控left_shoulder_x_norm = lm.landmark[lmPose.LEFT_SHOULDER].x  # 左肩膀(11点)x 坐标-归一化left_shoulder_y_norm = lm.landmark[lmPose.LEFT_SHOULDER].y  # 左肩膀(11点)y 坐标-归一化right_shoulder_x_norm = lm.landmark[lmPose.RIGHT_SHOULDER].x  # 右肩膀(12点)x 坐标-归一化right_shoulder_y_norm = lm.landmark[lmPose.RIGHT_SHOULDER].y  # 右肩膀(12点)y 坐标-归一化results = all_detection(nose_x, nose_y,left_eye_inner_x, left_eye_inner_y,right_eye_inner_x, right_eye_inner_y,left_ear_x, left_ear_y,right_ear_x, right_ear_y,left_mouth_x, left_mouth_y,right_mouth_x, right_mouth_y,left_shoulder_x, left_shoulder_y,right_shoulder_x, right_shoulder_y,left_shoulder_x_norm, left_shoulder_y_norm,right_shoulder_x_norm, right_shoulder_y_norm)print(results)mp_drawing.draw_landmarks(image, keypoints.pose_landmarks, mp_pose.POSE_CONNECTIONS)cv2.imshow("Image", image)if cv2.waitKey(1) & 0xFF == ord('q'):breakcap.release()
cv2.destroyAllWindows()

需要注意的是utils.py中的判定指标不是固定的,根据摄像头的位置动态调整才能达到满意的效果。

😺四、参考

Google:pose_landmarker
LearnOpencv:building-a-body-posture-analysis-system-using-mediapipe

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18781.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5个免费下载音乐的网站,喜欢听什么就搜什么

以下5个音乐下载网站&#xff0c;中国人不骗中国人&#xff0c;全部免费。个个曲库丰富&#xff0c;喜欢听什么就搜什么&#xff0c;还能下载mp3格式&#xff0c;点赞收藏即刻拥有&#xff01; 1、MyFreeMP3 tools.liumingye.cn/music/ MyFreeMP3是一个提供音乐播放和下载服…

富凡行是什么软件,来具体聊一聊它的详情,感兴趣的不要错过了

目前做网络项目的人很多&#xff0c;也就衍生出了很多的软件、项目、平台。接触过了很多的产品&#xff0c;感触颇深&#xff0c;确实市面上的东西差别都很大&#xff0c;有好的&#xff0c;有不好的。 我也是喜欢在网上做点副业&#xff0c;自己捣鼓一下&#xff0c;毕竟互联网…

2024-5-29 石群电路-17

2024-5-29&#xff0c;星期三&#xff0c;17:26&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴.今天又是阳光明媚的一天&#xff0c;没有什么特别的事情发生&#xff0c;给女朋友做了好吃的&#xff0c;吃了西瓜&#xff0c;加油学习&#xff0c;嘻嘻嘻~~~~ 今…

四川易点慧电商抖音小店信誉之店

在当下这个电商飞速发展的时代&#xff0c;如何在众多网店中挑选出一家既可靠又值得信赖的店铺&#xff0c;成为了消费者们关注的焦点。四川易点慧电子商务有限公司抖音小店以其卓越的品质和诚信的经营&#xff0c;逐渐在抖音平台上崭露头角&#xff0c;成为了众多消费者心中的…

HDRnet

local feature and global feature 在这里插入图片描述 Local features and Global features in Image Local feature also known as local descriptors, are distinct, informative characteristics of an image or video frame that are used in computer vision and image…

redis--集群节点维护

添加节点 因公司业务发展迅猛&#xff0c;现有的三主三从redis cluster架构可能无法满足现有业务的并发写入需求&#xff0c;因此公司紧急采购一台服务器192.168.7.107&#xff0c;需要将其动态添加到集群当中其不能影响业务使用和数据丢失&#xff0c;则添加过程如下: 同步之…

Pandas-中axis的用法

在Pandas中&#xff0c;min(axis)方法是计算DataFrame或Series中每行或每列的最小值的函数。该函数可以接受一个参数axis&#xff0c;用于指定计算最小值的方向。当axis0时&#xff0c;表示沿着行的方向计算最小值&#xff1b;当axis1时&#xff0c;表示沿着列的方向计算最小值…

买入看跌期权怎么理解?

今天带你了解买入看跌期权怎么理解&#xff1f;看跌期权买入者往往预期市场价格将下跌。 买入看跌期权怎么理解&#xff1f; 买入看跌期权是指购买者支付权利金&#xff0c;获得以特定价格向期权出售者卖出一定数量的某种特定商品的权利。看跌期权买入者往往预期市场价格将下跌…

【YOLOv5/v7改进系列】引入AKConv——即插即用的卷积块

一、导言 介绍了一种名为AKConv&#xff08;Alterable Kernel Convolution&#xff09;的新型卷积操作&#xff0c;旨在解决标准卷积操作存在的两个根本性问题。首先&#xff0c;标准卷积操作受限于局部窗口&#xff0c;无法捕获来自其他位置的信息&#xff0c;且其采样形状固…

软件系统测试的类型和方法介绍

测试是软件开发过程中至关重要的一环&#xff0c;负责验证和确认软件系统是否符合预期的需求&#xff0c;并帮助开发团队消除潜在的缺陷。系统测试作为软件测试中不可缺少的过程&#xff0c;是根据预先制定的测试计划和测试用例&#xff0c;以检查软件系统功能、性能、安全性和…

仿真51单片机程序(下载安装+Proteus)

我是看的这个大佬的:http://t.csdnimg.cn/Z07SZ 大佬写的很详细了,我就不献丑了. 贴上俩个运行成功的截图,有碰到问题的欢迎交流.

【学习Day2】计算机基础

✍&#x1f3fb;记录学习过程中的输出&#xff0c;坚持每天学习一点点~ ❤️希望能给大家提供帮助~欢迎点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb;指点&#x1f64f; 1.4 校验码 奇偶校验 ● 奇偶校验码的编码方法是&#xff1a; 由若干位有效信息的头部或者…

探寻数据处理的高效之道:从Python内置方法到NumPy的飞跃

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言&#xff1a;为什么要学习NumPy&#xff1f; 二、案例展示&#xff1a;创建整数序列…

idm软件是做什么的 IDM是啥软件 idm软件怎么下载 idm软件怎么下载

一、IDM是啥软件 IDM 是由美国 Tonec 公司开发的 Windows 软件&#xff0c;该软件最初于 2005 年发布。IDM全称Internet Download Manager&#xff0c;是一款Windows平台老牌而功能强大的下载加速器&#xff0c;专注于互联网数据下载。这款软件是一款不错的轻量级下载工具&…

关于如何在 smartforms 中 debug

发现一旦smartforms 复杂起来&#xff0c;Debug的时候就一下子找不到指定位置&#xff0c;所以如何才能最简单的找到指定位置呢 以这个为案例 然后打上断点即可debug

相对论表明速度越快时间越慢,为什么速度会影响时间?

在物理学的宏伟殿堂中&#xff0c;相对论以其深邃的洞察力&#xff0c;挑战了我们对时间和空间的传统认识。1905年&#xff0c;阿尔伯特爱因斯坦提出了狭义相对论&#xff0c;揭示了在所有惯性参照系中&#xff0c;光速是常数的惊人事实。 随后在1915年&#xff0c;他进一步发展…

YOLOv5数据集的文件结构和文件格式以及标注工具LabelImg的说明文档

文章目录 一 概述二 文件结构与数据格式2.1 数据集的文件结构2.2 数据格式2.2 文件结构2.3 标注文件的注意事项 三 手动标注YOLOv5数据集3.1 标注工具的选择3.2 标注流程 四 总结与注意事项4.1 labelImg的使用技巧与说明4.2 注意事项 一 概述 YOLOv5 是一个采用深度学习技…

基于匹配追踪和最大重叠离散小波变换的ECG心电信号R波检测(MATLAB 2018a)

准确识别心电信号的R波是进行HRV分析的前提。因此&#xff0c;开发出准确的心电信号R波检测方法十分重要。近几十年来&#xff0c;提出的R峰检测方法主要分为两个阶段。第1阶段是预处理阶段&#xff0c;目的是对受不同噪声影响的原始心电信号进行降噪处理&#xff0c;从而实现增…

基于SpringBoot+Html+Mysql的餐厅点餐管理系统外卖点餐系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

算法与数据结构高手养成:朴素的贪心法(上)最优化策略

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…