使用mediapipe识别视频中的人物动作
导入必要的库
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('动作错误')
原文地址: http://www.cveoy.top/t/topic/gudD 著作权归作者所有。请勿转载和采集!