Mediapipe人体姿态识别与动作分类Python教程

项目概述

本项目利用Mediapipe强大的姿态估计能力,结合OpenCV图像处理库,实现了对视频中人体姿态的实时识别,并根据预先训练的动作分类模型,对识别结果进行分类。

功能实现

  1. 使用Mediapipe检测视频帧中的人体关键点。
  2. 计算关键点之间的角度,提取人体姿态特征。
  3. 根据不同文件夹的图片数据,训练动作分类模型。
  4. 实时识别视频中的人体动作,并将结果显示在画面上。

代码实现

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_drawingmp_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实现人体姿态识别和动作分类,并提供了一些优化建议和面试自我介绍的参考。希望这篇教程能够帮助你入门计算机视觉领域,开发出更多有趣的应用。

Mediapipe人体姿态识别与动作分类Python教程

原文地址: https://www.cveoy.top/t/topic/gqIl 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录