Mediapipe人体姿态识别与动作分类Python教程
Mediapipe人体姿态识别与动作分类Python教程
项目概述
本项目利用Mediapipe强大的姿态估计能力,结合OpenCV图像处理库,实现了对视频中人体姿态的实时识别,并根据预先训练的动作分类模型,对识别结果进行分类。
功能实现
- 使用Mediapipe检测视频帧中的人体关键点。
- 计算关键点之间的角度,提取人体姿态特征。
- 根据不同文件夹的图片数据,训练动作分类模型。
- 实时识别视频中的人体动作,并将结果显示在画面上。
代码实现
import cv2
import mediapipe as mp
import math
# 初始化MediaPipe的人体姿势模型
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
# 打开输入视频文件
cap = cv2.VideoCapture('6.mp4')
# 获取输入视频的帧率和分辨率
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 创建输出视频文件
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter('9_1.mp4', fourcc, fps, (width, height))
i = 0
poses = ''
a = 1 # 拟合精度
# 处理视频文件中的每一帧
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
# 读取一帧
ret, frame = cap.read()
if not ret:
break
# 将帧转换为RGB格式
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 处理人体姿势检测
results = pose.process(image)
# 判断是否检测到人体
if results.pose_landmarks:
# 绘制人体骨架
mp_drawing.draw_landmarks(
frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2), connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 0, 255), thickness=2, circle_radius=2))
# ... 获取关键点坐标 ...
# ... 计算角度 ...
# ... 根据角度判断动作 ...
# ... 在画面上显示结果 ...
# 绘制头部关键点
nose = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE]
x, y = int(nose.x * width), int(nose.y * height)
cv2.circle(frame, (x, y), 5, (255, 0, 0), -1)
else:
# 如果未检测到人体,则跳过本帧处理
cv2.putText(frame, 'No body detected', (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
# ... 将帧写入输出视频文件 ...
# ... 显示当前帧的结果 ...
# ... 检测是否按下q键退出 ...
# ... 释放资源 ...
代码讲解
1. 初始化Mediapipe
import mediapipe as mp
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
# ...
- 导入
mediapipe库。 - 初始化
mp_drawing和mp_pose对象,用于绘制关键点和处理姿态估计。 - 使用
with语句创建pose对象,设置检测置信度阈值。
2. 读取视频帧
cap = cv2.VideoCapture('6.mp4')
while cap.isOpened():
ret, frame = cap.read()
# ...
- 使用
cv2.VideoCapture()打开视频文件。 - 在循环中使用
cap.read()读取每一帧图像。
3. 姿态估计
results = pose.process(image)
if results.pose_landmarks:
# ...
- 使用
pose.process()对图像帧进行姿态估计。 - 检查
results.pose_landmarks是否为空,判断是否检测到人体。
4. 绘制关键点和骨架
mp_drawing.draw_landmarks(
frame, results.pose_landmarks, mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=mp_drawing.DrawingSpec(color=(0, 255, 0), thickness=2, circle_radius=2), connection_drawing_spec=mp_drawing.DrawingSpec(color=(255, 0, 255), thickness=2, circle_radius=2))
- 使用
mp_drawing.draw_landmarks()绘制关键点和骨架线。 - 可以自定义关键点和线条的颜色、粗细等参数。
5. 获取关键点坐标
right_knee = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE]
- 通过
results.pose_landmarks.landmark访问各个关键点的坐标信息。 - 可以使用
mp_pose.PoseLandmark枚举类型获取特定关键点的索引。
6. 计算角度
angle = math.degrees(math.atan2(right_wrist.y - right_ankle.y, right_wrist.x - right_ankle.x) -
math.atan2(right_knee.y - right_ankle.y, right_knee.x - right_ankle.x))
- 使用
math.atan2()计算两个向量之间的夹角,并使用math.degrees()将弧度转换为角度。
7. 动作分类
if (angle >= -16.5*a and angle <= -8/a) and (angle_dr > 179/a and angle_dr <= 186*a or angle_dl > 182/a and angle_dl <= 191*a):
poses = 'warm-up'
- 根据计算出的角度值,设置阈值判断当前动作。
8. 显示结果
cv2.putText(frame, poses, (5, 20),
cv2.FONT_HERSHEY_COMPLEX_SMALL, 1.5, (225, 100, 225), 2)
cv2.imshow('MediaPipe Pose Detection press q exit', frame)
- 使用
cv2.putText()将识别结果显示在画面上。 - 使用
cv2.imshow()显示处理后的图像帧。
优化建议
- 可以根据实际应用场景调整检测置信度阈值,以平衡识别精度和速度。
- 可以使用更高效的算法进行角度计算,例如向量点积。
- 可以使用机器学习模型代替硬编码的阈值判断,提高动作分类的准确性和鲁棒性。
- 可以将处理后的视频帧保存到文件或流媒体服务器,实现远程监控和分析。
面试自我介绍
1分钟版本
大家好,我叫冯楠,是黑龙江大学电子工程学院物联网工程专业的一名学生。我热爱编程和机器学习,对计算机视觉领域充满热情。在校期间,我积极参与科研项目,熟练掌握了Python、OpenCV等工具,并成功开发了基于Mediapipe的人体姿态识别系统。我具备良好的沟通能力和团队合作精神,乐于学习和接受挑战。感谢大家的聆听!
总结
本教程介绍了如何使用Mediapipe和OpenCV实现人体姿态识别和动作分类,并提供了一些优化建议和面试自我介绍的参考。希望这篇教程能够帮助你入门计算机视觉领域,开发出更多有趣的应用。
原文地址: https://www.cveoy.top/t/topic/gqIl 著作权归作者所有。请勿转载和采集!