diff --git a/src/js/pose_viewer/src/index.html b/src/js/pose_viewer/src/index.html
index b4a5d76..aa983d9 100644
--- a/src/js/pose_viewer/src/index.html
+++ b/src/js/pose_viewer/src/index.html
@@ -77,12 +77,7 @@
setTimeout(() => {
poseViewer.setAttribute('src', url + 'test');
- }, 2000);
-
- poseViewer.addEventListener('render$', (e) => {
- console.log(poseViewer.shadowRoot.querySelector('canvas').width);
- console.log(poseViewer.shadowRoot.querySelector('canvas').height);
- });
+ }, 200);
// for(let i = 0; i < sentence.length; i++) {
diff --git a/src/python/pose_format/utils/generic.py b/src/python/pose_format/utils/generic.py
new file mode 100644
index 0000000..60538b8
--- /dev/null
+++ b/src/python/pose_format/utils/generic.py
@@ -0,0 +1,160 @@
+from typing import Tuple
+
+import numpy as np
+from numpy import ma
+from pose_format import Pose
+from pose_format.numpy import NumPyPoseBody
+from pose_format.pose_header import PoseHeader, PoseHeaderDimensions
+from pose_format.utils.normalization_3d import PoseNormalizer
+from pose_format.utils.openpose import OpenPose_Components
+
+
+def pose_hide_legs(pose: Pose):
+ if pose.header.components[0].name == "POSE_LANDMARKS":
+ point_names = ["KNEE", "ANKLE", "HEEL", "FOOT_INDEX"]
+ # pylint: disable=protected-access
+ points = [
+ pose.header._get_point_index("POSE_LANDMARKS", side + "_" + n)
+ for n in point_names
+ for side in ["LEFT", "RIGHT"]
+ ]
+ pose.body.data[:, :, points, :] = 0
+ pose.body.confidence[:, :, points] = 0
+ elif pose.header.components[0].name == "pose_keypoints_2d":
+ point_names = ["Hip", "Knee", "Ankle", "BigToe", "SmallToe", "Heel"]
+ # pylint: disable=protected-access
+ points = [
+ pose.header._get_point_index("pose_keypoints_2d", side + n)
+ for n in point_names
+ for side in ["L", "R"]
+ ]
+ pose.body.data[:, :, points, :] = 0
+ pose.body.confidence[:, :, points] = 0
+ else:
+ raise ValueError("Unknown pose header schema for hiding legs")
+
+
+def pose_shoulders(pose_header: PoseHeader):
+ if pose_header.components[0].name == "POSE_LANDMARKS":
+ return ("POSE_LANDMARKS", "RIGHT_SHOULDER"), ("POSE_LANDMARKS", "LEFT_SHOULDER")
+
+ if pose_header.components[0].name == "BODY_135":
+ return ("BODY_135", "RShoulder"), ("BODY_135", "LShoulder")
+
+ if pose_header.components[0].name == "pose_keypoints_2d":
+ return ("pose_keypoints_2d", "RShoulder"), ("pose_keypoints_2d", "LShoulder")
+
+ raise ValueError("Unknown pose header schema for normalization")
+
+
+def hands_indexes(pose_header: PoseHeader):
+ if pose_header.components[0].name == "POSE_LANDMARKS":
+ return [pose_header._get_point_index("LEFT_HAND_LANDMARKS", "MIDDLE_FINGER_MCP"),
+ pose_header._get_point_index("RIGHT_HAND_LANDMARKS", "MIDDLE_FINGER_MCP")]
+
+ if pose_header.components[0].name == "pose_keypoints_2d":
+ return [pose_header._get_point_index("hand_left_keypoints_2d", "M_CMC"),
+ pose_header._get_point_index("hand_right_keypoints_2d", "M_CMC")]
+
+
+def pose_normalization_info(pose_header: PoseHeader):
+ (c1, p1), (c2, p2) = pose_shoulders(pose_header)
+ return pose_header.normalization_info(p1=(c1, p1), p2=(c2, p2))
+
+
+def hands_components(pose_header: PoseHeader):
+ if pose_header.components[0].name in ["POSE_LANDMARKS", "LEFT_HAND_LANDMARKS", "RIGHT_HAND_LANDMARKS"]:
+ return ("LEFT_HAND_LANDMARKS", "RIGHT_HAND_LANDMARKS"), \
+ ("WRIST", "PINKY_MCP", "INDEX_FINGER_MCP"), \
+ ("WRIST", "MIDDLE_FINGER_MCP")
+
+ if pose_header.components[0].name in ["pose_keypoints_2d", "hand_left_keypoints_2d", "hand_right_keypoints_2d"]:
+ return ("hand_left_keypoints_2d", "hand_right_keypoints_2d"), \
+ ("BASE", "P_CMC", "I_CMC"), \
+ ("BASE", "M_CMC")
+
+ raise ValueError("Unknown pose header")
+
+
+def normalize_component_3d(pose, component_name: str, plane: Tuple[str, str, str], line: Tuple[str, str]):
+ hand_pose = pose.get_components([component_name])
+ plane = hand_pose.header.normalization_info(p1=(component_name, plane[0]),
+ p2=(component_name, plane[1]),
+ p3=(component_name, plane[2]))
+ line = hand_pose.header.normalization_info(p1=(component_name, line[0]),
+ p2=(component_name, line[1]))
+ normalizer = PoseNormalizer(plane=plane, line=line)
+ normalized_hand = normalizer(hand_pose.body.data)
+
+ # Add normalized hand to pose
+ pose.body.data = ma.concatenate([pose.body.data, normalized_hand], axis=2).astype(np.float32)
+ pose.body.confidence = np.concatenate([pose.body.confidence, hand_pose.body.confidence], axis=2)
+
+
+def normalize_hands_3d(pose: Pose, left_hand=True, right_hand=True):
+ (left_hand_component, right_hand_component), plane, line = hands_components(pose.header)
+ if left_hand:
+ normalize_component_3d(pose, left_hand_component, plane, line)
+ if right_hand:
+ normalize_component_3d(pose, right_hand_component, plane, line)
+
+
+def fake_pose(num_frames: int, fps=25, dims=2, components=OpenPose_Components):
+ dimensions = PoseHeaderDimensions(width=1, height=1, depth=1)
+ header = PoseHeader(version=0.1, dimensions=dimensions, components=components)
+
+ total_points = header.total_points()
+ data = np.random.randn(num_frames, 1, total_points, dims)
+ confidence = np.random.randn(num_frames, 1, total_points)
+ masked_data = ma.masked_array(data)
+
+ body = NumPyPoseBody(fps=int(fps), data=masked_data, confidence=confidence)
+
+ return Pose(header, body)
+
+
+def correct_wrist(pose: Pose, hand: str) -> Pose:
+ wrist_index = pose.header._get_point_index(f'{hand}_HAND_LANDMARKS', 'WRIST')
+ wrist = pose.body.data[:, :, wrist_index]
+ wrist_conf = pose.body.confidence[:, :, wrist_index]
+
+ body_wrist_index = pose.header._get_point_index('POSE_LANDMARKS', f'{hand}_WRIST')
+ body_wrist = pose.body.data[:, :, body_wrist_index]
+ body_wrist_conf = pose.body.confidence[:, :, body_wrist_index]
+
+ new_wrist_data = ma.where(wrist.data == 0, body_wrist, wrist)
+ new_wrist_conf = ma.where(wrist_conf == 0, body_wrist_conf, wrist_conf)
+
+ pose.body.data[:, :, body_wrist_index] = ma.masked_equal(new_wrist_data, 0)
+ pose.body.confidence[:, :, body_wrist_index] = new_wrist_conf
+ return pose
+
+
+def correct_wrists(pose: Pose) -> Pose:
+ pose = correct_wrist(pose, 'LEFT')
+ pose = correct_wrist(pose, 'RIGHT')
+ return pose
+
+
+def reduce_holistic(pose: Pose) -> Pose:
+ if pose.header.components[0].name != "POSE_LANDMARKS":
+ return pose
+
+ import mediapipe as mp
+ points_set = set([p for p_tup in list(mp.solutions.holistic.FACEMESH_CONTOURS) for p in p_tup])
+ face_contours = [str(p) for p in sorted(points_set)]
+
+ ignore_names = [
+ "EAR", "NOSE", "MOUTH", "EYE", # Face
+ "THUMB", "PINKY", "INDEX", # Hands
+ "KNEE", "ANKLE", "HEEL", "FOOT_INDEX" # Feet
+ ]
+
+ body_component = [c for c in pose.header.components if c.name == 'POSE_LANDMARKS'][0]
+ body_no_face_no_hands = [p for p in body_component.points if all([i not in p for i in ignore_names])]
+
+ components = [c.name for c in pose.header.components if c.name != 'POSE_WORLD_LANDMARKS']
+ return pose.get_components(components, {
+ "FACE_LANDMARKS": face_contours,
+ "POSE_LANDMARKS": body_no_face_no_hands
+ })