深度学习篇---MediaPipe 及其人体姿态估计模型详解

发布于:2025-05-12 ⋅ 阅读:(113) ⋅ 点赞:(0)


前言

MediaPipe 是 Google 开发的一个开源跨平台框架,用于构建多模态(如视频、音频等)应用的机器学习管道。它特别适用于实时应用,提供了多种预训练模型,包括人脸检测、手势识别、人体姿态估计等。


一、MediaPipe 核心特点

跨平台支持

  1. 支持 Android、iOS、桌面平台(Windows、Linux、macOS
  2. 支持多种编程语言(Python、C++、JavaScript 等)
  3. 可以在 CPU 上高效运行,不需要专用 GPU

实时性能

  1. 优化后的模型可以在移动设备上实时运行
  2. 典型的人体姿态估计模型在高端手机上能达到 30+ FPS

模块化设计

  1. 提供预构建的解决方案(Solutions)
  2. 也可以自定义 ML 管道(Graphs)

预训练模型

  1. 提供多种开箱即用的模型
  2. 模型针对移动设备进行了优化

二、MediaPipe 人体姿态估计模型

MediaPipe 提供了两种主要的人体姿态估计解决方案:

1. MediaPipe Pose (BlazePose)

模型特点

####高精度
高精度:识别 33 个关键点(包括面部、躯干和四肢)

实时性能

实时性能:在移动设备上也能实时运行

两种变体

两种变体:

Lite

Lite:轻量级版本适合低端设备

Heavy

Heavy:高精度版本,适合性能较好的设备

关键点定义

模型检测的 33 个关键点包括:
0-9: 面部关键点
10: 右肩
11: 左肩
12: 右肘
13: 左肘
14: 右腕
15: 左腕
16-21: 右手关键点
22-27: 左手关键点
28: 右髋
29: 左髋
30: 右膝
31: 左膝
32: 右踝
33: 左踝

技术细节

使用了一种称为 BlazePose 的拓扑结构
采用两阶段检测方法:

检测器

检测器:定位人体边界框

关键点预测器

关键点预测器:在边界框内预测关键点

支持3D姿态估计

支持 3D 姿态估计(提供关键点的 z 坐标

2. MediaPipe Holistic

模型特点

更全面的检测

更全面的检测:同时检测人体姿态、面部关键点和手部关键点

543个关键点

543 个关键点:
33 个人体姿态关键点
468 个面部关键点
21×2=42 个手部关键点(每只手 21 个)

适用场景

需要同时分析全身姿态、面部表情和手势的应用
舞蹈动作分析、全身交互系统

三、模型性能比较

模型 关键点数 输入分辨率 推理时间(CPU) 适用场景
Pose Lite 33 256x256 ~5ms 移动设备实时应用
Pose Heavy 33 256x256 ~10ms 需要更高精度的应用
Holistic 543 256x256 ~15ms 需要全身分析的应用

四、Python API 使用详解

代码示例

import cv2
import mediapipe as mp

# 初始化模型
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(
    static_image_mode=False,  # 视频流模式
    model_complexity=1,       # 0: Lite, 1: Full, 2: Heavy
    smooth_landmarks=True,    # 平滑关键点
    enable_segmentation=False, # 是否输出分割掩码
    min_detection_confidence=0.5,
    min_tracking_confidence=0.5
)

# 处理图像
image = cv2.imread("image.jpg")
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)

# 获取关键点
if results.pose_landmarks:
    for landmark in results.pose_landmarks.landmark:
        print(f"x: {landmark.x}, y: {landmark.y}, z: {landmark.z}, visibility: {landmark.visibility}")

关键参数说明

static_image_mode

True:将输入视为静态图像,每帧都运行检测器
False:视频流模式,使用跟踪优化性能

model_complexity

0:Lite 版本
1:Full 版本(默认)
2:Heavy 版本

smooth_landmarks

启用时会对关键点进行时间平滑处理

enable_segmentation

启用时会输出人体分割掩码

min_detection_confidence

检测阶段的最小置信度阈值(0-1)

min_tracking_confidence

跟踪阶段的最小置信度阈值(0-1)

可视化关键点

mp_drawing = mp.solutions.drawing_utils

# 绘制关键点和连接线
annotated_image = image.copy()
mp_drawing.draw_landmarks(
    annotated_image,
    results.pose_landmarks,
    mp_pose.POSE_CONNECTIONS,
    landmark_drawing_spec=mp_drawing.DrawingSpec(color=(255,0,0), thickness=2),
    connection_drawing_spec=mp_drawing.DrawingSpec(color=(0,255,0), thickness=2)
)

cv2.imshow("Pose", annotated_image)
cv2.waitKey(0)

五、实际应用技巧

性能优化

对于视频流,使用 static_image_mode=False
根据需求选择合适的模型复杂度
降低输入分辨率可以提高速度

提高准确性

使用 Heavy 模型
确保人物在图像中足够大
适当调整置信度阈值

处理遮挡

利用 visibility 属性判断关键点是否可见
使用平滑处理减少抖动

3D 姿态利用

z 坐标表示深度(相对于髋部的相对深度)
可用于判断身体部位的相对位置

六、与其他姿态估计模型的比较

特性 MediaPipe Pose OpenPose MoveNet PoseNet
关键点数 33 25/18 17 17
3D 支持 是 否 否 否
移动端优化 优秀 一般 优秀 良好
实时性能 优秀 一般 优秀 良好
安装复杂度 低 高 中 中
语言支持 多语言 主要C++ Python/TF Python/TF

七、进阶应用示例

1. 计算关键点角度

def calculate_angle(a, b, c):
    """计算三个关键点之间的角度"""
    a = np.array([a.x, a.y])
    b = np.array([b.x, b.y])
    c = np.array([c.x, c.y])
    
    ba = a - b
    bc = c - b
    
    cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
    angle = np.arccos(cosine_angle)
    
    return np.degrees(angle)

# 计算肘部角度
if results.pose_landmarks:
    shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
    elbow = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW]
    wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST]
    
    angle = calculate_angle(shoulder, elbow, wrist)
    print(f"Elbow angle: {angle:.2f} degrees")

2. 姿势分类

def classify_posture(landmarks):
    # 获取关键点
    left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER]
    right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER]
    left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP]
    right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP]
    left_ear = landmarks[mp_pose.PoseLandmark.LEFT_EAR]
    
    # 计算脊柱角度
    spine_angle = calculate_angle(
        np.array([left_shoulder.x, left_shoulder.y-0.1]),  # 肩膀上方的点
        np.array([left_shoulder.x, left_shoulder.y]),
        np.array([left_hip.x, left_hip.y])
    )
    
    # 分类逻辑
    if 160 < spine_angle < 200:
        return "Good posture"
    else:
        return "Bad posture (slouching)"

八、常见问题解决

b检测不到人体

  1. 检查置信度阈值是否设置过高
  2. 确保人物在图像中足够大
  3. 尝试使用静态图像模式

关键点抖动

  1. 启用 smooth_landmarks=True
  2. 增加 min_tracking_confidence
  3. 在应用层添加额外的平滑滤波

性能问题

  1. 降低模型复杂度
  2. 减小输入图像尺寸
  3. 对于视频流,确保使用 static_image_mode=False

安装问题v3

  1. 确保使用最新版本的 MediaPipe
  2. 检查 Python 版本兼容性
  3. 在干净的环境中安装
    MediaPipe 的人体姿态估计模型为开发者提供了强大且易用的工具,特别适合需要实时性能的应用场景。通过合理配置参数适当的后处理,可以在各种应用中实现准确的人体姿态分析


网站公告

今日签到

点亮在社区的每一天
去签到