要实现 人体实时动作捕捉,可以使用计算机视觉技术,结合 OpenCV 和深度学习模型(如 MediaPipe、OpenPose、BlazePose 等)来检测人体的关键点(关节、骨骼),然后通过这些点计算动作和姿态。下面我将从 基础原理 到 代码实现,分步骤详细讲解。
一、动作捕捉的基本原理
人体动作捕捉的核心是 人体姿态估计,即在图像或视频中识别出人体的关键点(如头部、肩膀、肘部、膝盖等),并实时跟踪这些点的位置变化,从而推断出人体的动作。
常用的方法包括:
- 基于传统算法:如 HOG(方向梯度直方图)+ SVM,但精度低,难以应对复杂动作。
- 基于深度学习:
- MediaPipe Pose:Google 开源,轻量、高效,适合实时应用。
- OpenPose:卡内基梅隆大学开源,精度高,适合多人体检测。
- BlazePose:Google 针对移动端优化,速度快,适合手机、嵌入式设备。
- MMPose(基于 PyTorch):功能强大,支持多种模型,适合研究。
二、环境准备
我们需要安装以下库:
pip install opencv-python mediapipe numpy
- OpenCV:用于读取摄像头视频流。
- MediaPipe:用于人体姿态估计。
- NumPy:用于数据处理。
三、使用 MediaPipe 实现实时动作捕捉
1. 初始化 MediaPipe Pose 模型
import cv2
import mediapipe as mp
# 初始化 MediaPipe Pose
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
mp_drawing = mp.solutions.drawing_utils
2. 打开摄像头并实时检测
cap = cv2.VideoCapture(0) # 0 表示默认摄像头
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 转换为 RGB,因为 MediaPipe 需要 RGB 输入
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
# 如果检测到人体,绘制关键点和骨架
if results.pose_landmarks:
mp_drawing.draw_landmarks(
frame,
results.pose_landmarks,
mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(0, 0, 255), thickness=2)
)
# 显示结果
cv2.imshow('Real-time Pose Detection', frame)
# 按 'q' 退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
3. 输出关键点坐标
if results.pose_landmarks:
for idx, landmark in enumerate(results.pose_landmarks.landmark):
print(f"Point {idx}: ({landmark.x}, {landmark.y}, {landmark.z})")
四、动作识别与捕捉扩展
1. 动作识别(如举手、深蹲、跳跃)
可以通过计算关键点之间的角度或距离来判断动作。例如:
- 举手:判断手腕是否高于肩膀。
- 深蹲:计算膝盖和髋部的垂直距离变化。
- 跳跃:检测脚部是否离地。
示例代码(判断是否举手):
def is_hand_raised(landmarks):
# 获取左右手腕和肩膀的坐标
left_wrist = landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value]
right_wrist = landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value]
left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
# 判断手腕是否高于肩膀
left_raised = left_wrist.y < left_shoulder.y
right_raised = right_wrist.y < right_shoulder.y
return left_raised or right_raised
# 在主循环中调用
if results.pose_landmarks:
if is_hand_raised(results.pose_landmarks.landmark):
print("Hand raised!")
2. 动作捕捉数据保存
可以将关键点坐标保存为 CSV 或 JSON 文件,用于后续分析或训练模型。
import csv
with open('pose_data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['frame', 'point_id', 'x', 'y', 'z'])
frame_count = 0
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
results = pose.process(image_rgb)
if results.pose_landmarks:
for idx, landmark in enumerate(results.pose_landmarks.landmark):
writer.writerow([frame_count, idx, landmark.x, landmark.y, landmark.z])
frame_count += 1
五、进阶:使用 OpenPose 或 BlazePose
1. OpenPose
OpenPose 支持多人体检测,适合复杂场景。需要先安装 OpenPose(依赖 Caffe 和 CUDA)。
git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git
cd openpose
# 按照官方文档安装依赖
2. BlazePose
BlazePose 是 Google 针对移动端优化的模型,速度极快。
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(
model_complexity=0, # 0: BlazePose, 1/2: 更复杂的模型
smooth_landmarks=True,
enable_segmentation=True
)
六、应用场景
- 健身指导:实时检测深蹲、俯卧撑等动作是否标准。
- 手势控制:通过手势控制电脑或游戏。
- 动画制作:将动作捕捉数据导入 Blender、Maya 制作动画。
- 医疗康复:监测患者的康复动作是否正确。
七、总结
方法 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
MediaPipe Pose | 轻量、快速、易用 | 精度略低于 OpenPose | 实时应用、移动端 |
OpenPose | 高精度、支持多人体 | 安装复杂、资源消耗大 | 研究、多人体场景 |
BlazePose | 极快、适合移动端 | 功能相对较少 | 手机、嵌入式设备 |
推荐方案:
- 初学者或实时应用:MediaPipe Pose
- 需要高精度或多人体:OpenPose
- 移动端或嵌入式设备:BlazePose