@@ -190,3 +190,26 @@ def reduce_holistic(pose: Pose) -> Pose:
190
190
"FACE_LANDMARKS" : face_contours ,
191
191
"POSE_LANDMARKS" : body_no_face_no_hands
192
192
})
193
+
194
+
195
+ def is_left_handed (pose : Pose ) -> bool :
196
+ left_hand = pose .get_components (["LEFT_HAND_LANDMARKS" ])
197
+ right_hand = pose .get_components (["RIGHT_HAND_LANDMARKS" ])
198
+ left_hand_variance = np .nan_to_num (left_hand .body .data ).var (axis = 0 ).sum ()
199
+ left_hand_variance = left_hand_variance if left_hand_variance != 'masked' else 0
200
+ right_hand_variance = np .nan_to_num (right_hand .body .data ).var (axis = 0 ).sum ()
201
+ right_hand_variance = right_hand_variance if right_hand_variance != 'masked' else 0
202
+ return left_hand_variance > right_hand_variance
203
+
204
+
205
+ def flip_holistic (pose : Pose ) -> Pose :
206
+ FLIPPED_COMPONENTS = ["POSE_LANDMARKS" , "FACE_LANDMARKS" , "RIGHT_HAND_LANDMARKS" , "LEFT_HAND_LANDMARKS" ]
207
+ FLIPPED_BODY_POINTS = ['NOSE' , 'RIGHT_EYE_INNER' , 'RIGHT_EYE' , 'RIGHT_EYE_OUTER' , 'LEFT_EYE_INNER' , 'LEFT_EYE' , 'LEFT_EYE_OUTER' , 'RIGHT_EAR' , 'LEFT_EAR' , 'MOUTH_RIGHT' , 'MOUTH_LEFT' , 'RIGHT_SHOULDER' , 'LEFT_SHOULDER' , 'RIGHT_ELBOW' , 'LEFT_ELBOW' , 'RIGHT_WRIST' , 'LEFT_WRIST' , 'RIGHT_PINKY' , 'LEFT_PINKY' , 'RIGHT_INDEX' , 'LEFT_INDEX' , 'RIGHT_THUMB' , 'LEFT_THUMB' , 'RIGHT_HIP' , 'LEFT_HIP' , 'RIGHT_KNEE' , 'LEFT_KNEE' , 'RIGHT_ANKLE' , 'LEFT_ANKLE' , 'RIGHT_HEEL' , 'LEFT_HEEL' , 'RIGHT_FOOT_INDEX' , 'LEFT_FOOT_INDEX' ]
208
+ # face flipping based on https://storage.googleapis.com/mediapipe-assets/documentation/mediapipe_face_landmark_fullsize.png
209
+ # CAUTION: works on reduced set of face keypoints (face_contours) only
210
+ FLIPPED_FACE_POINTS = ['0' , '249' , '10' , '13' , '14' , '17' , '251' , '263' , '267' , '269' , '270' , '276' , '282' , '283' , '284' , '285' , '288' , '291' , '293' , '295' , '296' , '297' , '300' , '308' , '310' , '311' , '312' , '314' , '317' , '318' , '321' , '323' , '324' , '332' , '334' , '336' , '338' , '356' , '361' , '362' , '365' , '373' , '374' , '375' , '377' , '378' , '379' , '152' , '380' , '381' , '382' , '384' , '385' , '386' , '387' , '388' , '389' , '390' , '397' , '398' , '400' , '402' , '405' , '409' , '415' , '454' , '466' , \
211
+ '7' , '21' , '33' , '37' , '39' , '40' , '46' , '52' , '53' , '54' , '55' , '58' , '61' , '63' , '65' , '66' , '67' , '70' , '78' , '80' , '81' , '82' , '84' , '87' , '88' , '91' , '93' , '95' , '103' , '105' , '107' , '109' , '127' , '132' , '133' , '136' , '144' , '145' , '146' , '148' , '149' , '150' , '153' , '154' , '155' , '157' , '158' , '159' , '160' , '161' , '162' , '163' , '172' , '173' , '176' , '178' , '181' , '185' , '191' , '234' , '246' ]
212
+ body = [p for p in FLIPPED_BODY_POINTS if p in pose .header .components [0 ].points ]
213
+ face = [p for p in FLIPPED_FACE_POINTS if p in pose .header .components [1 ].points ]
214
+ pose = pose .flip (0 ).get_components (FLIPPED_COMPONENTS , {"POSE_LANDMARKS" : body , "FACE_LANDMARKS" : face })
215
+ return pose
0 commit comments