人体姿态角度提取算法:基于MediaPipe的骨骼关键点分析
人体姿态角度提取算法:基于MediaPipe的骨骼关键点分析
本算法使用MediaPipe库提取人体姿态的骨骼关键点信息,并计算不同关键点之间的角度,用于训练机器学习模型。
算法描述
1. 算法名称:骨骼角度提取算法
2. 功能:
通过使用MediaPipe库提取人体姿态的骨骼关键点信息,并计算出不同关键点之间的角度,用于训练机器学习模型。
3. 输入和输出:
- 输入: 包含不同动作图片的文件夹。
- 输出: 保存不同动作的骨骼角度信息的CSV文件。
4. 算法流程:
- 导入所需的库,包括mediapipe、cv2和pandas。
- 初始化mediapipe库中的姿势识别模型。
- 遍历不同动作的文件夹,读取图片并将其转换为RGB格式。
- 使用mediapipe库中的姿势识别模型提取人体姿态的骨骼关键点信息。
- 计算不同关键点之间的角度,包括腿与右手的角度、左臀、左膝和左踝的角度、右臀、右膝和右踝的角度、右肩、右肘和右手腕的角度、左肩、左肘和左手腕的角度、左髋、左膝和左踝的角度、腰部、左髋和左肩的角度、右髋、右膝和右踝的角度、腰部、右髋和右肩的角度、鼻子、右肩和右手腕的角度。
- 将角度添加到角度列表中。
- 在图像上绘制骨骼关键点。
- 保存绘制好骨骼关键点的图像。
- 将角度列表保存为CSV文件。
5. 复杂度分析:
- 时间复杂度: 遍历不同动作的文件夹和处理每张图片的时间复杂度为O(n),其中n为图片数量。计算每张图片的角度的时间复杂度为O(1),因此总时间复杂度为O(n)。
- 空间复杂度: 需要存储每张图片的角度信息,因此空间复杂度为O(n)。
代码示例
import mediapipe as mp
import cv2
import os
import pandas as pd
import math
# 定义保存骨骼角度的函数
def save_angles(angles_list, action_name, folder_name):
filename = f'{folder_name}_{action_name}.csv'
df = pd.DataFrame(angles_list, columns=['label' , 'angle1', 'angle2', 'angle3','angle4','angle5','angle6', 'angle7','angle8','angle9','angle10','angle11'])
df.to_csv(filename, index=False)
print(f'{filename} saved successfully')
# 初始化mediapipe
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
# 遍历不同动作的文件夹
for folder_name in os.listdir('actions'):
# 创建一个空的角度列表
angles_list = []
# 遍历文件夹中的所有图片
for filename in os.listdir(f'actions/{folder_name}'):
# 读取图片
image = cv2.imread(f'actions/{folder_name}/{filename}')
# 将图片转换为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 = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE]
right_ankle = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE]
right_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]
# 获取左肩、左肘和左手腕关键点的信息
left_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
left_elbow = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW]
left_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST]
# 获取右肩、右肘和右手腕关键点的信息
right_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
right_elbow = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW]
right_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]
# 获取左臀、左膝和左踝关键点的信息
left_hip = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP]
left_knee = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_KNEE]
left_ankle = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ANKLE]
# 获取右臀、右膝和右踝关键点的信息
right_hip = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP]
right_knee = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE]
right_ankle = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE]
# 获取左肩、左肘和左手腕关键点的信息 new
left_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
left_elbow = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW]
left_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST]
# 计算腿与右手的角度
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))
# 获取左肩、左肘和左手腕
angle1 = 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))
# 获取左臀、左膝和左踝
angle_dl = math.degrees(math.atan2(left_ankle.y - left_knee.y, left_ankle.x - left_knee.x) -
math.atan2(left_hip.y - left_knee.y, left_hip.x - left_knee.x))
# 获取右臀、右膝和右踝
angle_dr = math.degrees(math.atan2(right_ankle.y - right_knee.y, right_ankle.x - right_knee.x) -
math.atan2(right_hip.y - right_knee.y, right_hip.x - right_knee.x))
# 获取右肩、右肘和右手腕
angle_tr = math.degrees(math.atan2(right_wrist.y - right_elbow.y, right_wrist.x - right_elbow.x) -
math.atan2(right_shoulder.y - right_elbow.y, right_shoulder.x - right_elbow.x))
# 获取左肩、左肘和左手腕 new
angle_tl = math.degrees(math.atan2(left_wrist.y - left_elbow.y, left_wrist.x - left_elbow.x) -
math.atan2(left_shoulder.y - left_elbow.y, left_shoulder.x - left_elbow.x))
##############
#获取左髋、左膝和左踝关键点的信息
left_hip = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP]
left_knee = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_KNEE]
left_ankle = results.pose_landmarks.landmark[mp_pose.PoseLandmark.LEFT_ANKLE]
# 获取左髋、左膝和左踝的角度
angle_lka = math.degrees(math.atan2(left_ankle.y - left_knee.y, left_ankle.x - left_knee.x) -
math.atan2(left_hip.y - left_knee.y, left_hip.x - left_knee.x))
# 获取腰部、左髋和左肩的角度
waist = results.pose_landmarks.landmark[12]
angle_hls = math.degrees(math.atan2(left_shoulder.y - waist.y, left_shoulder.x - waist.x) -
math.atan2(left_hip.y - waist.y, left_hip.x - waist.x))
# 获取右髋、右膝和右踝关键点的信息
right_hip = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP]
right_knee = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_KNEE]
right_ankle = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ANKLE]
# 获取右髋、右膝和右踝的角度
angle_rka = math.degrees(math.atan2(right_ankle.y - right_knee.y, right_ankle.x - right_knee.x) -
math.atan2(right_hip.y - right_knee.y, right_hip.x - right_knee.x))
# 获取腰部、右髋和右肩的角度
angle_hrs = math.degrees(math.atan2(right_shoulder.y - waist.y, right_shoulder.x - waist.x) -
math.atan2(right_hip.y - waist.y, right_hip.x - waist.x))
##################
# 获取鼻子、右肩和右手腕关键点的信息
nose = results.pose_landmarks.landmark[mp_pose.PoseLandmark.NOSE]
right_shoulder = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
right_wrist = results.pose_landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]
# 获取鼻子、右肩和右手腕的角度
angle_nwr = math.degrees(math.atan2(right_wrist.y - nose.y, right_wrist.x - nose.x) -
math.atan2(right_shoulder.y - nose.y, right_shoulder.x - nose.x))
# 将角度添加到角度列表中
angles_list.append([folder_name , angle, angle1, angle_dl , angle_dr , angle_tr , angle_tl,angle_lka,angle_hls,angle_rka,angle_hrs,angle_nwr])
# 在图像上绘制骨骼
annotated_image = image.copy()
mp_drawing.draw_landmarks(annotated_image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS)
# 保存绘制好骨骼的图像
cv2.imwrite(f'annotated_images/{filename}', cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR))
# 将角度列表保存为csv文件
save_angles(angles_list, folder_name, 'dataset')
总结
本算法通过使用MediaPipe库提取人体姿态的骨骼关键点信息,并计算不同关键点之间的角度,可以有效地提取人体姿态信息,并将其用于训练机器学习模型。
原文地址: https://www.cveoy.top/t/topic/gLZF 著作权归作者所有。请勿转载和采集!