MediaPipe 是 Google 提供的一款跨平台开源框架,专注于计算机视觉、机器学习等领域的实时处理。它提供了一些非常强大的工具和模型,其中 人体姿态估计 和 手指关键点检测 功能被广泛应用于手势识别、运动分析等领域。
本篇教程将带你了解如何使用 MediaPipe 进行人体姿态估计和手指关键点检测,并提供详细的代码示例、图解和使用说明。
一、安装 MediaPipe 和 OpenCV
要使用 MediaPipe 进行人体姿态和手指检测,首先需要安装 mediapipe
和 opencv-python
库。你可以通过以下命令安装:
pip install mediapipe opencv-python
二、人体姿态检测(Pose Estimation)
MediaPipe 提供了一个预训练的 Pose 模型,可以帮助我们检测人体的各个关节点,包括头部、肩膀、肘部、膝盖等。
1. 导入所需的库
import cv2
import mediapipe as mp
2. 初始化 MediaPipe 模型
# 初始化 MediaPipe Pose 模型
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
# 初始化绘制工具
mp_drawing = mp.solutions.drawing_utils
3. 捕获视频并检测姿态
# 打开摄像头
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 将 BGR 图像转换为 RGB 图像
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# 进行姿态检测
results = pose.process(image)
# 将图像转换回 BGR
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# 绘制关键点
if results.pose_landmarks:
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
# 显示结果
cv2.imshow("Pose Estimation", image)
# 按 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
4. 代码说明
- pose.process(): 用于获取图像中人体的关键点。
- mp_drawing.draw_landmarks(): 用于在图像中绘制人体的关键点和连接线。
- results.pose_landmarks: 包含人体的 33 个关键点(例如:肩膀、肘部、膝盖等)。
5. 结果
你会看到摄像头窗口中会实时显示人体的 33 个关键点以及这些关键点之间的连线。可以通过 cv2.imshow
显示检测结果,并按 q
键退出。
6. 关键点信息
MediaPipe 人体姿态估计模型提供了 33 个关键点,它们包括但不限于:
- 头部(鼻子、眼睛、耳朵)
- 肩膀、肘部、手腕、臀部、膝盖、脚踝
你可以通过 results.pose_landmarks.landmark
获取每个关键点的位置,代码示例:
if results.pose_landmarks:
for id, landmark in enumerate(results.pose_landmarks.landmark):
print(f"Keypoint {id}: x={landmark.x}, y={landmark.y}, z={landmark.z}")
三、手指关键点检测(Hand Keypoints)
MediaPipe 还提供了一个预训练的 Hand 模型,可以帮助我们检测手指的关键点。每只手有 21 个关键点,用于表示手指和手掌的位置。
1. 初始化 MediaPipe 手部模型
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5)
2. 手指检测代码
# 打开摄像头
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 将 BGR 图像转换为 RGB 图像
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# 进行手指检测
results = hands.process(image)
# 将图像转换回 BGR
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# 绘制手指关键点
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# 显示结果
cv2.imshow("Hand Keypoints", image)
# 按 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
3. 代码说明
- hands.process(): 用于获取图像中的手指关键点。
- mp_drawing.draw_landmarks(): 用于绘制手指关键点和连接线。
- results.multi_hand_landmarks: 返回检测到的所有手的关键点(每只手包含 21 个关键点)。
4. 手指关键点信息
每只手有 21 个关键点,包括:
- 手腕
- 五个手指(每个手指有 4 个关键点)
你可以通过 results.multi_hand_landmarks
获取每只手的关键点位置,代码示例如下:
if results.multi_hand_landmarks:
for hand_landmarks in results.multi_hand_landmarks:
for id, landmark in enumerate(hand_landmarks.landmark):
print(f"Hand {id}: x={landmark.x}, y={landmark.y}, z={landmark.z}")
四、整合人体姿态与手指检测
下面是一个完整的例子,整合了人体姿态和手指检测:
import cv2
import mediapipe as mp
# 初始化 MediaPipe 模型
mp_pose = mp.solutions.pose
pose = mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_hands = mp.solutions.hands
hands = mp_hands.Hands(min_detection_confidence=0.5, min_tracking_confidence=0.5)
mp_drawing = mp.solutions.drawing_utils
# 打开摄像头
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 将图像转换为 RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# 进行姿态检测
pose_results = pose.process(image)
# 进行手指检测
hands_results = hands.process(image)
# 将图像转换回 BGR
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
# 绘制人体关键点
if pose_results.pose_landmarks:
mp_drawing.draw_landmarks(image, pose_results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
# 绘制手指关键点
if hands_results.multi_hand_landmarks:
for hand_landmarks in hands_results.multi_hand_landmarks:
mp_drawing.draw_landmarks(image, hand_landmarks, mp_hands.HAND_CONNECTIONS)
# 显示结果
cv2.imshow("Pose and Hand Keypoints", image)
# 按 'q' 键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
五、总结
通过 MediaPipe,我们可以非常轻松地实现人体姿态估计和手指关键点检测。通过结合 Pose
和 Hands
模型,我们可以同时检测人体姿态和手指动作,并进行实时可视化展示。
主要要点:
- MediaPipe 提供了强大的人体姿态和手指关键点检测模型。
- 使用
Pose
模型可以检测人体 33 个关键点。 - 使用
Hands
模型可以检测手的 21 个关键点。 - 可以结合 OpenCV 和 Pygame 进行图像处理和可视化。
你可以在此基础上进一步拓展,实现手势识别、人体行为分析等功能。