导入必要的库

import mediapipe as mp import cv2 import pandas as pd import math

定义函数,计算角度

def calculate_angle(a, b, c): ''' a: tuple(x, y) 坐标 b: tuple(x, y) 坐标 c: tuple(x, y) 坐标

return:
    计算的角度
'''
# 计算向量ab和向量bc的内积
angle_radian = math.acos((b[0]-a[0])*(c[0]-b[0])+(b[1]-a[1])*(c[1]-b[1]))/(math.sqrt((b[0]-a[0])**2+(b[1]-a[1])**2)*math.sqrt((c[0]-b[0])**2+(c[1]-b[1])**2))
# 将弧度转换为角度
angle_degree = math.degrees(angle_radian)
return angle_degree

定义函数,判断动作

def judge_action(video_path, angles_threshold): ''' video_path: 视频路径 angles_threshold: 角度阈值,用于判断动作是否正确

return:
    True: 动作正确
    False: 动作错误
'''
# 初始化mediapipe
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose

# 读取视频
cap = cv2.VideoCapture(video_path)

# 创建一个空的角度列表
angles_list = []

# 处理视频中的每一帧
while cap.isOpened():
    # 读取一帧
    success, image = cap.read()
    if not success:
        break

    # 将图片转换为RGB格式
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

    # 处理图片,提取骨骼
    with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
        results = pose.process(image)
        if results.pose_landmarks is None:
            continue

        # 获取右膝、右踝和右手腕关键点的信息
        right_knee = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE].y * image.shape[0]))
        right_ankle = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE].y * image.shape[0]))
        right_wrist = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].y * image.shape[0]))

        # 获取左肩、左肘和左手腕关键点的信息
        left_shoulder = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER].y * image.shape[0]))
        left_elbow = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW].y * image.shape[0]))
        left_wrist = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST].y * image.shape[0]))

        # 获取左臀、左膝和左踝关键点的信息
        left_hip = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP].y * image.shape[0]))
        left_knee = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_KNEE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_KNEE].y * image.shape[0]))
        left_ankle = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ANKLE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ANKLE].y * image.shape[0]))

        # 获取右臀、右膝和右踝关键点的信息
        right_hip = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP].y * image.shape[0]))
        right_knee = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE].y * image.shape[0]))
        right_ankle = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE].y * image.shape[0]))

        # 获取右肩、右肘和右手腕关键点的信息
        right_shoulder = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER].y * image.shape[0]))
        right_elbow = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW].y * image.shape[0]))
        right_wrist = (int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].x * image.shape[1]), int(results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST].y * image.shape[0]))

        # 计算腿与右手的角度
        angle = calculate_angle(right_knee, right_ankle, right_wrist)

        # 获取左肩、左肘和左手腕
        angle1 = calculate_angle(right_knee, right_ankle, left_wrist)

        # 获取左臀、左膝和左踝
        angle_dl = calculate_angle(left_ankle, left_knee, left_hip)

        # 获取右臀、右膝和右踝
        angle_dr = calculate_angle(right_ankle, right_knee, right_hip)

        # 获取右肩、右肘和右手腕
        angle_tr = calculate_angle(right_elbow, right_wrist, right_shoulder)

        # 将角度添加到角度列表中
        angles_list.append([angle, angle1, angle_dl, angle_dr, angle_tr])

        # 在图像上绘制骨骼
        annotated_image = image.copy()
        mp_drawing.draw_landmarks(annotated_image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)

        # 显示图像
        cv2.imshow('annotated_image', cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR))
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

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

# 将角度列表保存为csv文件
df = pd.DataFrame(angles_list, columns=['angle1', 'angle2', 'angle3', 'angle4', 'angle5'])
df.to_csv('test_angles.csv', index=False)

# 读取训练好的模型
model = pd.read_csv('dataset_model.csv')

# 判断动作是否正确
for i in range(5):
    if abs(df.iloc[:, i].mean() - model.iloc[0, i]) > angles_threshold:
        return False
return True

判断1.mp4中的人物动作是否正确

if judge_action('1.mp4', 5): print('动作正确') else: print('动作错误')

使用mediapipe识别视频中的人物动作

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

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