拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Mediapipe Holistic Tracking:人体姿态、手部与面部关键点统一追踪实践

简介面向人体姿态估计与手势识别学习者的 Mediapipe 整体跟踪工具基于谷歌开源库 Mediapipe 的 Python API 实现可对视频中的人脸、手部与人体姿态关键点进行同步检测与跟踪广泛应用于动作分析、健身辅助、虚拟数字人等场景。项目内置命令行入口只需通过 -i、-o、-f 分别指定输入视频路径、输出路径和模型参数即可运行结构精简适合初学者快速理解整体跟踪流程也便于开发者在此基础上扩展为实时摄像头或批量视频处理。资源包共 2 个文件分别为 app.py 核心脚本和 README.md 使用说明整体体积仅 2KB轻量无冗余方便直接阅读和修改。目前已有 812 人学习下载。读者可获得完整可运行的跟踪脚本、清晰的调用说明以及针对视频整体跟踪场景的实践参考对入门 Mediapipe 应用开发有直接帮助。1. 项目概述这到底在追什么1.1 一句话讲清 Holistic Tracking 是什么Mediapipe-Holistic-Tracking 这个项目本质上是用 Google 开源的 Mediapipe 框架把**人体姿态Pose、手部关键点Hands和面部关键点Face**三套检测模型统一到同一条视频流里实现对人体上半身甚至全身的 360 度无死角追踪。为什么叫 Holistic因为它是整体的、全息的而不是只盯着某一个部位。过去你要做手部追踪得单独跑一个 Hands 模型要做姿态估计又得单独跑一个 Pose 模型要做面部关键点还得再折腾一个 FaceMesh。三个模型各跑各的输出结果坐标系还不统一光是数据对齐就够写几百行代码。Mediapipe Holistic 把这三种能力打包成一个统一的 Pipeline一次推理同时输出 543 个关键点面部 468 个、左手 21 个、右手 21 个、姿态 33 个而且这些关键点的坐标在同一个归一化坐标系下直接就能用不需要你去做坐标变换。对于做动作捕捉、健身计数、手势识别、虚拟形象驱动、康复评估这类应用的人来说这个项目能省掉大量底层工作把精力集中在业务逻辑上。这篇博文适合刚接触 Mediapipe 的初学者也适合已经跑通过 Pose 或 Hands、想整合成完整人体追踪方案的开发者。1.2 和单独用 Pose、Hands 有什么区别我先说一个很多人容易忽略的点Holistic 并不是简单地把 Mediapipe 的三个解决方案Pose、Hands、FaceMesh顺序调了一遍而是用 Pose 模型先粗略定位人体区域再用这个结果去引导 Hands 和 Face 模型做精细检测。这样有两个好处手部和面部的 ROI感兴趣区域不需要在整张图上搜索计算量大幅下降所以整体 FPS 反而比你顺序跑三个模型要高。因为都在同一个 Pipeline 里三个子模型之间天然共享了帧数据和时间戳不会出现三个模型各处理各的帧、导致结果错位的问题。我实测下来同样的 CPU 机器上顺序跑三个模型大概只有 8-12 FPS而用 Holistic 可以稳定在 15-20 FPS。在 GPU 上差距更明显。所以如果你要做实时应用Holistic 是比 Pose Hands FaceMesh 三合一 更合理的选择。2. 环境准备最小可运行的依赖组合2.1 版本选择与 Python 环境先强调一个版本搭配问题。Mediapipe 的 API 在不同版本之间有过几次比较大的调整尤其是mp.solutions.holistic这个模块的参数名称和返回结构在 0.8.x 到 0.10.x 之间就有区别。我这边用的组合是Python 3.8 - 3.10 都可以建议用 3.9 或 3.10太老的 Python 版本可能装不上新版 Mediapipe。Mediapipe 0.10.7 或更高版本0.10.x 系列都行。OpenCV-Python 4.8.0 以上用于读取摄像头和绘制结果。NumPy 1.24 以上用于坐标数据处理。组件推荐版本说明Python3.9 - 3.10兼容性最好踩坑最少mediapipe0.10.7API 稳定参数命名统一opencv-python4.8.0视频流读取和图像绘制numpy1.24坐标数组处理2.2 安装步骤与初始化安装没什么复杂的一条命令搞定pip install mediapipe opencv-python numpy如果你是在国内网络环境下安装建议加上国内 PyPI 镜像源速度会快很多pip install mediapipe opencv-python numpy -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后先跑一个最小的初始化测试确认 Holistic 能正常加载模型权重。我第一次跑的时候卡在模型下载上很久后来才发现 Mediapipe 会在首次运行时自动从网络下载模型文件。如果下载失败需要手动把模型文件放到~/.mediapipe/目录下或者检查网络环境。这里有个经验如果代码运行后长时间无响应八成是模型文件在下拉耐心等一下就行。3. 核心代码实现从摄像头到完整骨架3.1 初始化 Holistic 模型与视频流先看一段最核心的代码实现把整个流程串起来import cv2 import mediapipe as mp mp_holistic mp.solutions.holistic mp_drawing mp.solutions.drawing_utils mp_drawing_styles mp.solutions.drawing_styles # 初始化 Holistic 模型 holistic mp_holistic.Holistic( static_image_modeFalse, # 视频流模式 model_complexity1, # 模型复杂度0轻量、1完整、2高精度 smooth_landmarksTrue, # 姿态关键点平滑 enable_segmentationFalse, # 不需要背景分割就关掉 min_detection_confidence0.5, # 检测置信度阈值 min_tracking_confidence0.5 # 追踪置信度阈值 ) cap cv2.VideoCapture(0) # 读取默认摄像头 while cap.isOpened(): success, frame cap.read() if not success: break # BGR 转 RGBMediapipe 要求 RGB 输入 image cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) image.flags.writeable False # 执行推理 results holistic.process(image) # 转回 BGR 用于 OpenCV 绘制 image.flags.writeable True image cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 在图像上绘制三种关键点 mp_drawing.draw_landmarks( image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS, landmark_drawing_specmp_drawing_styles.get_default_pose_landmarks_style() ) mp_drawing.draw_landmarks( image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS, landmark_drawing_specmp_drawing_styles.get_default_hand_landmarks_style() ) mp_drawing.draw_landmarks( image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS, landmark_drawing_specmp_drawing_styles.get_default_hand_landmarks_style() ) cv2.imshow(Mediapipe Holistic, image) if cv2.waitKey(5) 0xFF 27: # ESC 退出 break cap.release() cv2.destroyAllWindows()这段代码的核心就三件事初始化模型、循环读帧推理、绘制关键点。static_image_mode这个参数很多人容易搞混。它是用来区分图片模式和视频模式的。视频模式下Mediapipe 会利用帧与帧之间的时序信息做关键点追踪速度更快也更平滑图片模式下则只针对单帧检测。对实时摄像头应用保持False就行。如果你是要离线处理一堆图片那才设成True。model_complexity也是调优重点。0 是最轻量级的模型速度快但精度一般1 是平衡模式2 是最精细的模型关键点抖动更少但计算量也更大。在普通 CPU 上推荐用 1GPU 上可以放心上 2。3.2 关键点数据结构与坐标换算推理结果results里包含四个主要字段face_landmarks、pose_landmarks、left_hand_landmarks、right_hand_landmarks。每个字段都是一个NormalizedLandmarkList里面每个关键点有x、y、z三个坐标值并且是归一化坐标——x和y的取值范围是 0 到 1相对于图像宽度和高度的比例z表示深度单位与 x 相近越大表示离镜头越远。归一化坐标最大的好处是不受输入图像分辨率影响。你无论用 640x480 还是 1280x720 的输入拿到的坐标都是 0-1 之间的浮点数。但如果你需要换算成像素坐标就得手动乘回去h, w, _ image.shape # 以鼻尖关键点为例Pose 中鼻尖索引是 0 if results.pose_landmarks: nose results.pose_landmarks.landmark[0] nose_x_pixel int(nose.x * w) nose_y_pixel int(nose.y * h) print(f鼻尖像素坐标: ({nose_x_pixel}, {nose_y_pixel}))这里有个很实用的技巧z坐标虽然在 Mediapipe 里是近似值精度不算高但在做手势识别时非常有用。比如判断手是朝镜头伸还是远离镜头只看z的变化方向就够了不需要精确的深度值。4. 三个子模型的协作机制与细节解析4.1 为什么三个模型能同时工作Mediapipe Holistic 内部实际上是一个基于图Graph的 Pipeline。它在 Pose 模型输出的基础上把每个关键点的位置映射为手部和面部的中心点候选区域然后在这个小区域里再做精细检测。这个设计非常聪明因为手和脸在画面中通常只占很小一部分全图跑一遍检测成本太高而有了 Pose 的先验位置信息就只需要在小图块上推理。这个由粗到精的策略在日常生活中很像你先在大街上找到一个人Pose再凑近了看他是谁Face最后看他在做什么手势Hands。不是同时做三件事而是用上一步的结果帮下一步省力。4.2 不同子模型的坐标体系一致性我见过不少人在整合三个模型时被坐标系搞崩溃比如左手坐标和右手坐标搞反、或者 Face 坐标跟 Pose 坐标用了不同原点的系统。Holistic 的设计就省心得多了所有 543 个关键点都在同一个归一化坐标空间里直接可以算欧氏距离、角度不需要任何变换。不过有一个细节要特别注意左右手的判定是从人物视角出发的。也就是说画面中你看到的左边那只手如果它属于被测人物的右手那么它会被放进right_hand_landmarks而不是left_hand_landmarks。这个在视觉上有点反直觉做手势识别时一定要记得这一点否则左右手逻辑会完全反掉。我在这上面吃过亏后来给代码加了条注释# 注意这是目标对象的左右不是画面左右。关键点索引方面Pose 有 33 个关键点常用的有索引部位索引部位0鼻尖11左肩12右肩13左肘14右肘15左手腕16右手腕23左髋24右髋27左踝28右踝32右脚跟Hand 有 21 个关键点索引 0 是腕部1-4 是大拇指5-8 是食指9-12 是中指13-16 是无名指17-20 是小拇指。Face 有 468 个关键点通常用轮廓、眉毛、眼睛、嘴唇等特定索引的组合来提取特征。5. 踩坑记录与性能调优5.1 常见问题速查表我把跑这个项目时遇到的高频问题整理成了一张表方便你排查问题现象可能原因解决方案启动很慢卡在初始化首次运行需下载模型文件等待或手动下载模型放到~/.mediapipe/FPS 极低个位数model_complexity太高或输入分辨率太大降到 0 或 1把输入帧缩放至 640px 宽手部关键点频繁消失手离身体太远或手部区域太小拉近镜头增大输入分辨率提高追踪置信度阈值关键点剧烈抖动没有开启平滑或光照条件差设smooth_landmarksTrue改善光照均匀度左右手对调混淆了画面视角与人物视角检查是left_hand_landmarks还是right_hand_landmarks多人同时入镜Holistic 只支持单人裁剪 ROI 只保留目标人物或换用检测框先定位这里要详细说一下关键点抖动的问题。抖动在高要求的动捕场景下是个大麻烦比如你要用关键点去驱动一个虚拟角色手部坐标一跳一跳的话角色就会疯狂抽搐。除了打开smooth_landmarks我自己用得最多的办法是加一个一阶低通滤波对关键点的坐标做平滑import numpy as np class LandmarkSmoother: def __init__(self, alpha0.6): self.alpha alpha self.prev None def apply(self, landmarks): if landmarks is None: return None current np.array([[lm.x, lm.y, lm.z] for lm in landmarks]) if self.prev is None or self.prev.shape ! current.shape: self.prev current else: self.prev self.alpha * self.prev (1 - self.alpha) * current return self.prev smoother LandmarkSmoother(alpha0.5) # 在循环中使用 smoothed smoother.apply(results.pose_landmarks.landmark)alpha越大表示历史权重越高轨迹越平滑但响应也越慢alpha越小则越跟手。我一般取 0.4 到 0.6 之间既能滤掉高频抖动又不会让动作看起来飘。5.2 性能提升的实操思路如果你在追求更高帧率按照下面的顺序优化收益最大第一优先级是减小输入分辨率。很多手机摄像头默认输出 1080p但 Holistic 检测时并不需要那么高的分辨率内部甚至会把图缩到更小去跑。所以你在读帧后先缩放到 640x480 或者 512x512推理速度可以翻倍关键点精度几乎不受影响。第二优先级是调低model_complexity。复杂度从 2 降到 1在 CPU 上大概能提升 30%-50% 的推理速度。如果你的场景只是简单的挥手检测用 0 也可以。第三优先级是只画可见的关键点。有时候手被身体挡住results.right_hand_landmarks会是None绘制前先判断一下能避免不少无用计算代码也更健壮if results.left_hand_landmarks: mp_drawing.draw_landmarks( image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS )还有一个小技巧把摄像头帧率验证一遍。有的 USB 摄像头名义上支持 30FPS但实际输出只有 15FPS。你可以在循环里算一下实际帧率import time prev_time time.time() while cap.isOpened(): # ... 推理代码 ... current_time time.time() fps 1 / (current_time - prev_time) prev_time current_time cv2.putText(image, fFPS: {fps:.1f}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)实测下来很多所谓卡顿问题其实是摄像头本身的输出瓶颈而不是 Mediapipe 的问题。6. 这玩意儿还能怎么玩应用扩展方向6.1 动作识别与健身计数拿到 543 个关键点之后最经典的应用就是动作识别。不需要训练复杂的深度学习模型只需要根据关键点之间的角度变化就能判断动作。比如做俯卧撑计数看肘关节Pose 13/14 号点的角度变化身体下降时角度变小撑起时角度变大一个完整的波形就是一次俯卧撑。手肘角度计算代码def calculate_angle(a, b, c): 计算三点之间的角度度 import math a np.array([a.x, a.y]) b np.array([b.x, b.y]) c np.array([c.x, c.y]) radians math.atan2(c[1]-b[1], c[0]-b[0]) - \ math.atan2(a[1]-b[1], a[0]-b[0]) angle abs(radians * 180.0 / math.pi) return angle # 左肘关键点Pose 13 if results.pose_landmarks: landmark results.pose_landmarks.landmark left_elbow_angle calculate_angle(landmark[11], landmark[13], landmark[15]) print(f左手肘角度: {left_elbow_angle:.1f})这种方案在跳舞评分、动作对比、健身纠正等场景下非常实用全流程只需摄像头加一段 Python 代码成本极低。6.2 虚拟形象驱动与康复评估另一个很有想象力的方向是虚拟数字人驱动。用 Holistic 的关键点数据去驱动 Unity、Blender 里的骨骼模型关键在于把归一化坐标映射到虚拟骨骼的旋转角度。经典做法是对每个关节计算三点的空间向量利用向量的夹角确定对应骨骼的旋转欧拉角。因为 Holistic 的坐标都统一了这个映射逻辑对全身、双手、面部都通用代码模板可以复用。在康复医疗场景里Holistic 可以辅助做帕金森患者的运动评估、中风患者的上肢动作范围测量等。医生不需要给患者佩戴任何传感器只用普通摄像头就能完成初步筛查。这类应用对数据平滑的要求更高通常我会把smooth_landmarks打开并且在后处理阶段用更复杂的平滑算法如 Savitzky-Golay 滤波或者卡尔曼滤波进一步降低噪声。还有一个方向是手势控制。配合 21 个手部关键点做 PPT 翻页、音量调节、鼠标控制都没问题。手势分类也很简单算一下手指之间的夹角和距离就能判断是握拳、张开还是食指指向前方。比起数据手套或者深度摄像头Holistic 只需要一个 RGB 摄像头成本优势非常明显。7. 写在最后的个人体会跑通 Mediapipe Holistic 之后我最大的感受是它能让你在几小时之内就做出以前需要一两周才能完成的原型。人体关键点追踪的技术本身已经很成熟但对于大多数非算法团队来说真正困难的是把模型工程化、产品化。Holistic 把最大的一块硬骨头啃了下来剩下的就看你自己的创意了。如果你是在做实时交互类的产品我建议你在项目早期就把性能预算想清楚。帧率不是等做完功能再优化的而是在设计时就该定好的约束。先想清楚你的目标设备是什么CPU 还是 GPU支持什么分辨率然后针对这些约束去调整参数而不是一味追求检测精度。最后给个扩展建议这个项目的代码结构非常适合封装成独立的 Python 模块。把初始化、推理、绘制分离分别做成函数或类之后无论是做 Web 应用Flask Socket 推流、还是桌面客户端都能直接复用。我目前就在用这套封装做一个小型的体感游戏原型后续如果有心得再来分享。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门