Pose-Detection-App / skeleton_generator.py
vertalius's picture
Upload 12 files
1e91e1d verified
import numpy as np
class SkeletonGenerator:
def __init__(self, custom_mapping=None):
# Define default Maya-compatible bone names and their corresponding MediaPipe indices
self.bone_mapping = {
# Root & Spine
'Hips': 23, # HIPS/Pelvis
'Spine': 24, # Lower spine
'Spine1': 12, # Mid spine
'Spine2': 11, # Upper spine
# Head & Neck
'Neck': 11, # BASE_NECK
'Head': 0, # HEAD (using nose as reference)
# Left Arm Chain
'LeftShoulder': 11, # LEFT_SHOULDER
'LeftArm': 13, # LEFT_UPPER_ARM
'LeftForeArm': 15, # LEFT_LOWER_ARM
'LeftHand': 15, # LEFT_HAND (using wrist as reference)
# Right Arm Chain
'RightShoulder': 12, # RIGHT_SHOULDER
'RightArm': 14, # RIGHT_UPPER_ARM
'RightForeArm': 16, # RIGHT_LOWER_ARM
'RightHand': 16, # RIGHT_HAND (using wrist as reference)
# Left Leg Chain
'LeftUpLeg': 23, # LEFT_UPPER_LEG
'LeftLeg': 25, # LEFT_LOWER_LEG
'LeftFoot': 27, # LEFT_FOOT
'LeftToeBase': 31, # LEFT_TOE
# Right Leg Chain
'RightUpLeg': 24, # RIGHT_UPPER_LEG
'RightLeg': 26, # RIGHT_LOWER_LEG
'RightFoot': 28, # RIGHT_FOOT
'RightToeBase': 32, # RIGHT_TOE
}
def generate_skeleton(self, landmarks):
"""
Convert MediaPipe landmarks to Maya-compatible skeleton data
"""
if landmarks is None:
return None
skeleton_data = {}
# Convert landmarks to skeleton joint positions
for bone_name, landmark_idx in self.bone_mapping.items():
position = landmarks[landmark_idx]
rotation = self._calculate_bone_rotation(landmarks, landmark_idx)
# Convert NumPy arrays to regular Python lists
skeleton_data[bone_name] = {
'position': position.tolist(),
'rotation': rotation.tolist()
}
return skeleton_data
def _calculate_bone_rotation(self, landmarks, landmark_idx):
"""
Calculate bone rotation based on connected landmarks
"""
# Simple rotation calculation - can be enhanced for better accuracy
rotation = np.zeros(3)
if landmark_idx > 0:
# Calculate rotation based on parent-child relationship
parent_idx = landmark_idx - 1
direction = landmarks[landmark_idx] - landmarks[parent_idx]
# Convert direction to euler angles (simplified)
rotation[0] = np.arctan2(direction[1], direction[2]) # pitch
rotation[1] = np.arctan2(direction[0], direction[2]) # yaw
rotation[2] = np.arctan2(direction[0], direction[1]) # roll
return rotation