人体姿势识别:使用 MediaPipe 和 KNN 分类器识别动作

本代码演示如何使用 MediaPipe 和 KNN 分类器识别视频中的动作。它首先从视频文件中提取人体姿势信息,然后使用 KNN 分类器对动作进行分类,并最终在视频上显示识别结果。

import cv2
import mediapipe as mp
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier

# 初始化MediaPipe的人体姿势模型
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

# 打开输入视频文件
cap = cv2.VideoCapture('9.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))

# 加载动作数据集
warmup_df = pd.read_csv('dataset_1.csv')
combat_df = pd.read_csv('dataset_3.csv')
attack_df = pd.read_csv('dataset_2.csv')
respect_df = pd.read_csv('dataset_4.csv')
gongbu_df = pd.read_csv('dataset_5.csv')

# 将数据集合并为一个大的数据集
data = pd.concat([warmup_df, combat_df, attack_df, respect_df,gongbu_df], ignore_index=True)

# 训练KNN分类器
knn = KNeighborsClassifier(n_neighbors=3)
knn.fit(data.iloc[:, :-1], data['label'])

# 处理视频文件中的每一帧
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)

            # 获取人体姿势信息
            pose_data = []
            keypoints = [0, 11, 12, 13, 14, 15, 16, 23, 24, 25, 26, 27, 28]  # 需要的关键点的索引
            for i in keypoints:
                landmark = results.pose_landmarks.landmark[i]
                if landmark.visibility < 0.5:  # 如果关键点可见度小于0.5,则跳过
                    continue
                pose_data.append(landmark.x)
                pose_data.append(landmark.y)
                # pose_data.append(landmark.z if landmark.z is not None else 0)

            # 将姿势信息输入KNN分类器进行预测
            label = knn.predict([pose_data])

            # 在输出图片上显示动作类型
            cv2.putText(frame, label[0], (5, 60),
                        cv2.FONT_HERSHEY_SIMPLEX, 1.1, (255, 100, 100), 2)

        else:
            # 如果未检测到人体,则跳过本帧处理
            cv2.putText(frame, 'No body detected', (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)

        # 将帧写入输出视频文件
        out.write(frame)

        # 显示当前帧的结果
        cv2.imshow('MediaPipe Pose Detection press q exit', frame)

        # 检测是否按下q键退出
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()

## 报错 `ValueError: Unknown label type: 'continuous'` 解决内容

该错误通常是由于KNN分类器的标签类型不正确导致的。请确保数据集中的标签是离散的,而不是连续的。如果标签是连续的,可以考虑将其转换为离散的标签,例如将一个连续的数值范围划分为几个离散的类别。另外,还可以尝试使用其他类型的分类器,例如决策树分类器或支持向量机分类器。

代码解释:

  1. 导入必要的库:cv2 用于视频处理,mediapipe 用于人体姿势检测,pandas 用于数据操作,sklearn.neighbors 用于 KNN 分类器。
  2. 初始化 MediaPipe 的人体姿势模型。
  3. 打开输入视频文件并获取其帧率和分辨率。
  4. 创建输出视频文件。
  5. 加载动作数据集。
  6. 将数据集合并为一个大的数据集。
  7. 训练 KNN 分类器。
  8. 循环处理视频中的每一帧。
    • 读取一帧。
    • 将帧转换为 RGB 格式。
    • 使用 MediaPipe 处理人体姿势检测。
    • 如果检测到人体,则绘制人体姿势并获取人体姿势信息。
    • 将姿势信息输入 KNN 分类器进行预测。
    • 在输出图片上显示动作类型。
    • 如果未检测到人体,则跳过本帧处理。
    • 将帧写入输出视频文件。
    • 显示当前帧的结果。
  9. 检测是否按下 q 键退出。
  10. 释放资源。

代码中需要注意的点:

  • 确保动作数据集中的标签是离散的,而不是连续的。
  • 可以根据需要调整关键点索引和 KNN 分类器的参数。
  • 可以根据需要调整输出视频文件的名称。

使用该代码需要安装以下库:

  • OpenCV
  • MediaPipe
  • Pandas
  • Scikit-learn

使用方法:

  1. 将输入视频文件和动作数据集文件放在代码同一目录下。
  2. 运行代码。
  3. 在视频窗口中按下 q 键退出。

代码示例:

# 加载动作数据集
warmup_df = pd.read_csv('dataset_1.csv')
combat_df = pd.read_csv('dataset_3.csv')
attack_df = pd.read_csv('dataset_2.csv')
respect_df = pd.read_csv('dataset_4.csv')
gongbu_df = pd.read_csv('dataset_5.csv')

# 将数据集合并为一个大的数据集
data = pd.concat([warmup_df, combat_df, attack_df, respect_df,gongbu_df], ignore_index=True)

示例动作数据集文件:

| x1 | y1 | x2 | y2 | ... | label | |---|---|---|---|---|---| | 0.1 | 0.2 | 0.3 | 0.4 | ... | 'warmup' | | 0.5 | 0.6 | 0.7 | 0.8 | ... | 'combat' | | ... | ... | ... | ... | ... | ... |

注:

  • 数据集文件中的标签应为字符串类型。
  • 数据集文件应包含所有动作的特征数据。
  • 数据集文件应与输入视频文件的动作类型一致。

其他:

  • 可以使用其他类型的分类器,例如决策树分类器或支持向量机分类器。
  • 可以使用其他类型的输入数据,例如图片或音频。
  • 可以根据需要调整代码的功能和性能。
人体姿势识别:使用 MediaPipe 和 KNN 分类器识别动作

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

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