Spaces:
Running
on
Zero
Running
on
Zero
| # Copyright 2024-2025 The Alibaba Wan Team Authors. All rights reserved. | |
| import os | |
| import cv2 | |
| import time | |
| import math | |
| import matplotlib | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| from typing import Dict, List | |
| import random | |
| from pose2d_utils import AAPoseMeta | |
| def draw_handpose(canvas, keypoints, hand_score_th=0.6): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| eps = 0.01 | |
| H, W, C = canvas.shape | |
| stickwidth = max(int(min(H, W) / 200), 1) | |
| edges = [ | |
| [0, 1], | |
| [1, 2], | |
| [2, 3], | |
| [3, 4], | |
| [0, 5], | |
| [5, 6], | |
| [6, 7], | |
| [7, 8], | |
| [0, 9], | |
| [9, 10], | |
| [10, 11], | |
| [11, 12], | |
| [0, 13], | |
| [13, 14], | |
| [14, 15], | |
| [15, 16], | |
| [0, 17], | |
| [17, 18], | |
| [18, 19], | |
| [19, 20], | |
| ] | |
| for ie, (e1, e2) in enumerate(edges): | |
| k1 = keypoints[e1] | |
| k2 = keypoints[e2] | |
| if k1 is None or k2 is None: | |
| continue | |
| if k1[2] < hand_score_th or k2[2] < hand_score_th: | |
| continue | |
| x1 = int(k1[0]) | |
| y1 = int(k1[1]) | |
| x2 = int(k2[0]) | |
| y2 = int(k2[1]) | |
| if x1 > eps and y1 > eps and x2 > eps and y2 > eps: | |
| cv2.line( | |
| canvas, | |
| (x1, y1), | |
| (x2, y2), | |
| matplotlib.colors.hsv_to_rgb([ie / float(len(edges)), 1.0, 1.0]) * 255, | |
| thickness=stickwidth, | |
| ) | |
| for keypoint in keypoints: | |
| if keypoint is None: | |
| continue | |
| if keypoint[2] < hand_score_th: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| x = int(x) | |
| y = int(y) | |
| if x > eps and y > eps: | |
| cv2.circle(canvas, (x, y), stickwidth, (0, 0, 255), thickness=-1) | |
| return canvas | |
| def draw_handpose_new(canvas, keypoints, stickwidth_type='v2', hand_score_th=0.6): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| eps = 0.01 | |
| H, W, C = canvas.shape | |
| if stickwidth_type == 'v1': | |
| stickwidth = max(int(min(H, W) / 200), 1) | |
| elif stickwidth_type == 'v2': | |
| stickwidth = max(max(int(min(H, W) / 200) - 1, 1) // 2, 1) | |
| edges = [ | |
| [0, 1], | |
| [1, 2], | |
| [2, 3], | |
| [3, 4], | |
| [0, 5], | |
| [5, 6], | |
| [6, 7], | |
| [7, 8], | |
| [0, 9], | |
| [9, 10], | |
| [10, 11], | |
| [11, 12], | |
| [0, 13], | |
| [13, 14], | |
| [14, 15], | |
| [15, 16], | |
| [0, 17], | |
| [17, 18], | |
| [18, 19], | |
| [19, 20], | |
| ] | |
| for ie, (e1, e2) in enumerate(edges): | |
| k1 = keypoints[e1] | |
| k2 = keypoints[e2] | |
| if k1 is None or k2 is None: | |
| continue | |
| if k1[2] < hand_score_th or k2[2] < hand_score_th: | |
| continue | |
| x1 = int(k1[0]) | |
| y1 = int(k1[1]) | |
| x2 = int(k2[0]) | |
| y2 = int(k2[1]) | |
| if x1 > eps and y1 > eps and x2 > eps and y2 > eps: | |
| cv2.line( | |
| canvas, | |
| (x1, y1), | |
| (x2, y2), | |
| matplotlib.colors.hsv_to_rgb([ie / float(len(edges)), 1.0, 1.0]) * 255, | |
| thickness=stickwidth, | |
| ) | |
| for keypoint in keypoints: | |
| if keypoint is None: | |
| continue | |
| if keypoint[2] < hand_score_th: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| x = int(x) | |
| y = int(y) | |
| if x > eps and y > eps: | |
| cv2.circle(canvas, (x, y), stickwidth, (0, 0, 255), thickness=-1) | |
| return canvas | |
| def draw_ellipse_by_2kp(img, keypoint1, keypoint2, color, threshold=0.6): | |
| H, W, C = img.shape | |
| stickwidth = max(int(min(H, W) / 200), 1) | |
| if keypoint1[-1] < threshold or keypoint2[-1] < threshold: | |
| return img | |
| Y = np.array([keypoint1[0], keypoint2[0]]) | |
| X = np.array([keypoint1[1], keypoint2[1]]) | |
| mX = np.mean(X) | |
| mY = np.mean(Y) | |
| length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
| angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
| polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
| cv2.fillConvexPoly(img, polygon, [int(float(c) * 0.6) for c in color]) | |
| return img | |
| def split_pose2d_kps_to_aa(kp2ds: np.ndarray) -> List[np.ndarray]: | |
| """Convert the 133 keypoints from pose2d to body and hands keypoints. | |
| Args: | |
| kp2ds (np.ndarray): [133, 2] | |
| Returns: | |
| List[np.ndarray]: _description_ | |
| """ | |
| kp2ds_body = ( | |
| kp2ds[[0, 6, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 17, 20]] | |
| + kp2ds[[0, 5, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 18, 21]] | |
| ) / 2 | |
| kp2ds_lhand = kp2ds[91:112] | |
| kp2ds_rhand = kp2ds[112:133] | |
| return kp2ds_body.copy(), kp2ds_lhand.copy(), kp2ds_rhand.copy() | |
| def draw_aapose_by_meta(img, meta: AAPoseMeta, threshold=0.5, stick_width_norm=200, draw_hand=True, draw_head=True): | |
| kp2ds = np.concatenate([meta.kps_body, meta.kps_body_p[:, None]], axis=1) | |
| kp2ds_lhand = np.concatenate([meta.kps_lhand, meta.kps_lhand_p[:, None]], axis=1) | |
| kp2ds_rhand = np.concatenate([meta.kps_rhand, meta.kps_rhand_p[:, None]], axis=1) | |
| pose_img = draw_aapose(img, kp2ds, threshold, kp2ds_lhand=kp2ds_lhand, kp2ds_rhand=kp2ds_rhand, stick_width_norm=stick_width_norm, draw_hand=draw_hand, draw_head=draw_head) | |
| return pose_img | |
| def draw_aapose_by_meta_new(img, meta: AAPoseMeta, threshold=0.5, stickwidth_type='v2', draw_hand=True, draw_head=True): | |
| kp2ds = np.concatenate([meta.kps_body, meta.kps_body_p[:, None]], axis=1) | |
| kp2ds_lhand = np.concatenate([meta.kps_lhand, meta.kps_lhand_p[:, None]], axis=1) | |
| kp2ds_rhand = np.concatenate([meta.kps_rhand, meta.kps_rhand_p[:, None]], axis=1) | |
| pose_img = draw_aapose_new(img, kp2ds, threshold, kp2ds_lhand=kp2ds_lhand, kp2ds_rhand=kp2ds_rhand, | |
| stickwidth_type=stickwidth_type, draw_hand=draw_hand, draw_head=draw_head) | |
| return pose_img | |
| def draw_hand_by_meta(img, meta: AAPoseMeta, threshold=0.5, stick_width_norm=200): | |
| kp2ds = np.concatenate([meta.kps_body, meta.kps_body_p[:, None] * 0], axis=1) | |
| kp2ds_lhand = np.concatenate([meta.kps_lhand, meta.kps_lhand_p[:, None]], axis=1) | |
| kp2ds_rhand = np.concatenate([meta.kps_rhand, meta.kps_rhand_p[:, None]], axis=1) | |
| pose_img = draw_aapose(img, kp2ds, threshold, kp2ds_lhand=kp2ds_lhand, kp2ds_rhand=kp2ds_rhand, stick_width_norm=stick_width_norm, draw_hand=True, draw_head=False) | |
| return pose_img | |
| def draw_aaface_by_meta(img, meta: AAPoseMeta, threshold=0.5, stick_width_norm=200, draw_hand=False, draw_head=True): | |
| kp2ds = np.concatenate([meta.kps_body, meta.kps_body_p[:, None]], axis=1) | |
| # kp2ds_lhand = np.concatenate([meta.kps_lhand, meta.kps_lhand_p[:, None]], axis=1) | |
| # kp2ds_rhand = np.concatenate([meta.kps_rhand, meta.kps_rhand_p[:, None]], axis=1) | |
| pose_img = draw_M(img, kp2ds, threshold, kp2ds_lhand=None, kp2ds_rhand=None, stick_width_norm=stick_width_norm, draw_hand=draw_hand, draw_head=draw_head) | |
| return pose_img | |
| def draw_aanose_by_meta(img, meta: AAPoseMeta, threshold=0.5, stick_width_norm=100, draw_hand=False): | |
| kp2ds = np.concatenate([meta.kps_body, meta.kps_body_p[:, None]], axis=1) | |
| # kp2ds_lhand = np.concatenate([meta.kps_lhand, meta.kps_lhand_p[:, None]], axis=1) | |
| # kp2ds_rhand = np.concatenate([meta.kps_rhand, meta.kps_rhand_p[:, None]], axis=1) | |
| pose_img = draw_nose(img, kp2ds, threshold, kp2ds_lhand=None, kp2ds_rhand=None, stick_width_norm=stick_width_norm, draw_hand=draw_hand) | |
| return pose_img | |
| def gen_face_motion_seq(img, metas: List[AAPoseMeta], threshold=0.5, stick_width_norm=200): | |
| return | |
| def draw_M( | |
| img, | |
| kp2ds, | |
| threshold=0.6, | |
| data_to_json=None, | |
| idx=-1, | |
| kp2ds_lhand=None, | |
| kp2ds_rhand=None, | |
| draw_hand=False, | |
| stick_width_norm=200, | |
| draw_head=True | |
| ): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| new_kep_list = [ | |
| "Nose", | |
| "Neck", | |
| "RShoulder", | |
| "RElbow", | |
| "RWrist", # No.4 | |
| "LShoulder", | |
| "LElbow", | |
| "LWrist", # No.7 | |
| "RHip", | |
| "RKnee", | |
| "RAnkle", # No.10 | |
| "LHip", | |
| "LKnee", | |
| "LAnkle", # No.13 | |
| "REye", | |
| "LEye", | |
| "REar", | |
| "LEar", | |
| "LToe", | |
| "RToe", | |
| ] | |
| # kp2ds_body = (kp2ds.copy()[[0, 6, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 17, 20]] + \ | |
| # kp2ds.copy()[[0, 5, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 18, 21]]) / 2 | |
| kp2ds = kp2ds.copy() | |
| # import ipdb; ipdb.set_trace() | |
| kp2ds[[1,2,3,4,5,6,7,8,9,10,11,12,13,18,19], 2] = 0 | |
| if not draw_head: | |
| kp2ds[[0,14,15,16,17], 2] = 0 | |
| kp2ds_body = kp2ds | |
| # kp2ds_body = kp2ds_body[:18] | |
| # kp2ds_lhand = kp2ds.copy()[91:112] | |
| # kp2ds_rhand = kp2ds.copy()[112:133] | |
| limbSeq = [ | |
| # [2, 3], | |
| # [2, 6], # shoulders | |
| # [3, 4], | |
| # [4, 5], # left arm | |
| # [6, 7], | |
| # [7, 8], # right arm | |
| # [2, 9], | |
| # [9, 10], | |
| # [10, 11], # right leg | |
| # [2, 12], | |
| # [12, 13], | |
| # [13, 14], # left leg | |
| # [2, 1], | |
| [1, 15], | |
| [15, 17], | |
| [1, 16], | |
| [16, 18], # face (nose, eyes, ears) | |
| # [14, 19], | |
| # [11, 20], # foot | |
| ] | |
| colors = [ | |
| # [255, 0, 0], | |
| # [255, 85, 0], | |
| # [255, 170, 0], | |
| # [255, 255, 0], | |
| # [170, 255, 0], | |
| # [85, 255, 0], | |
| # [0, 255, 0], | |
| # [0, 255, 85], | |
| # [0, 255, 170], | |
| # [0, 255, 255], | |
| # [0, 170, 255], | |
| # [0, 85, 255], | |
| # [0, 0, 255], | |
| # [85, 0, 255], | |
| [170, 0, 255], | |
| [255, 0, 255], | |
| [255, 0, 170], | |
| [255, 0, 85], | |
| # foot | |
| # [200, 200, 0], | |
| # [100, 100, 0], | |
| ] | |
| H, W, C = img.shape | |
| stickwidth = max(int(min(H, W) / stick_width_norm), 1) | |
| for _idx, ((k1_index, k2_index), color) in enumerate(zip(limbSeq, colors)): | |
| keypoint1 = kp2ds_body[k1_index - 1] | |
| keypoint2 = kp2ds_body[k2_index - 1] | |
| if keypoint1[-1] < threshold or keypoint2[-1] < threshold: | |
| continue | |
| Y = np.array([keypoint1[0], keypoint2[0]]) | |
| X = np.array([keypoint1[1], keypoint2[1]]) | |
| mX = np.mean(X) | |
| mY = np.mean(Y) | |
| length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
| angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
| polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
| cv2.fillConvexPoly(img, polygon, [int(float(c) * 0.6) for c in color]) | |
| for _idx, (keypoint, color) in enumerate(zip(kp2ds_body, colors)): | |
| if keypoint[-1] < threshold: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| # cv2.circle(canvas, (int(x), int(y)), 4, color, thickness=-1) | |
| cv2.circle(img, (int(x), int(y)), stickwidth, color, thickness=-1) | |
| if draw_hand: | |
| img = draw_handpose(img, kp2ds_lhand, hand_score_th=threshold) | |
| img = draw_handpose(img, kp2ds_rhand, hand_score_th=threshold) | |
| kp2ds_body[:, 0] /= W | |
| kp2ds_body[:, 1] /= H | |
| if data_to_json is not None: | |
| if idx == -1: | |
| data_to_json.append( | |
| { | |
| "image_id": "frame_{:05d}.jpg".format(len(data_to_json) + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| ) | |
| else: | |
| data_to_json[idx] = { | |
| "image_id": "frame_{:05d}.jpg".format(idx + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| return img | |
| def draw_nose( | |
| img, | |
| kp2ds, | |
| threshold=0.6, | |
| data_to_json=None, | |
| idx=-1, | |
| kp2ds_lhand=None, | |
| kp2ds_rhand=None, | |
| draw_hand=False, | |
| stick_width_norm=200, | |
| ): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| new_kep_list = [ | |
| "Nose", | |
| "Neck", | |
| "RShoulder", | |
| "RElbow", | |
| "RWrist", # No.4 | |
| "LShoulder", | |
| "LElbow", | |
| "LWrist", # No.7 | |
| "RHip", | |
| "RKnee", | |
| "RAnkle", # No.10 | |
| "LHip", | |
| "LKnee", | |
| "LAnkle", # No.13 | |
| "REye", | |
| "LEye", | |
| "REar", | |
| "LEar", | |
| "LToe", | |
| "RToe", | |
| ] | |
| # kp2ds_body = (kp2ds.copy()[[0, 6, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 17, 20]] + \ | |
| # kp2ds.copy()[[0, 5, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 18, 21]]) / 2 | |
| kp2ds = kp2ds.copy() | |
| kp2ds[1:, 2] = 0 | |
| # kp2ds[0, 2] = 1 | |
| kp2ds_body = kp2ds | |
| # kp2ds_body = kp2ds_body[:18] | |
| # kp2ds_lhand = kp2ds.copy()[91:112] | |
| # kp2ds_rhand = kp2ds.copy()[112:133] | |
| limbSeq = [ | |
| # [2, 3], | |
| # [2, 6], # shoulders | |
| # [3, 4], | |
| # [4, 5], # left arm | |
| # [6, 7], | |
| # [7, 8], # right arm | |
| # [2, 9], | |
| # [9, 10], | |
| # [10, 11], # right leg | |
| # [2, 12], | |
| # [12, 13], | |
| # [13, 14], # left leg | |
| # [2, 1], | |
| [1, 15], | |
| [15, 17], | |
| [1, 16], | |
| [16, 18], # face (nose, eyes, ears) | |
| # [14, 19], | |
| # [11, 20], # foot | |
| ] | |
| colors = [ | |
| # [255, 0, 0], | |
| # [255, 85, 0], | |
| # [255, 170, 0], | |
| # [255, 255, 0], | |
| # [170, 255, 0], | |
| # [85, 255, 0], | |
| # [0, 255, 0], | |
| # [0, 255, 85], | |
| # [0, 255, 170], | |
| # [0, 255, 255], | |
| # [0, 170, 255], | |
| # [0, 85, 255], | |
| # [0, 0, 255], | |
| # [85, 0, 255], | |
| [170, 0, 255], | |
| # [255, 0, 255], | |
| # [255, 0, 170], | |
| # [255, 0, 85], | |
| # foot | |
| # [200, 200, 0], | |
| # [100, 100, 0], | |
| ] | |
| H, W, C = img.shape | |
| stickwidth = max(int(min(H, W) / stick_width_norm), 1) | |
| # for _idx, ((k1_index, k2_index), color) in enumerate(zip(limbSeq, colors)): | |
| # keypoint1 = kp2ds_body[k1_index - 1] | |
| # keypoint2 = kp2ds_body[k2_index - 1] | |
| # if keypoint1[-1] < threshold or keypoint2[-1] < threshold: | |
| # continue | |
| # Y = np.array([keypoint1[0], keypoint2[0]]) | |
| # X = np.array([keypoint1[1], keypoint2[1]]) | |
| # mX = np.mean(X) | |
| # mY = np.mean(Y) | |
| # length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
| # angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
| # polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
| # cv2.fillConvexPoly(img, polygon, [int(float(c) * 0.6) for c in color]) | |
| for _idx, (keypoint, color) in enumerate(zip(kp2ds_body, colors)): | |
| if keypoint[-1] < threshold: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| # cv2.circle(canvas, (int(x), int(y)), 4, color, thickness=-1) | |
| cv2.circle(img, (int(x), int(y)), stickwidth, color, thickness=-1) | |
| if draw_hand: | |
| img = draw_handpose(img, kp2ds_lhand, hand_score_th=threshold) | |
| img = draw_handpose(img, kp2ds_rhand, hand_score_th=threshold) | |
| kp2ds_body[:, 0] /= W | |
| kp2ds_body[:, 1] /= H | |
| if data_to_json is not None: | |
| if idx == -1: | |
| data_to_json.append( | |
| { | |
| "image_id": "frame_{:05d}.jpg".format(len(data_to_json) + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| ) | |
| else: | |
| data_to_json[idx] = { | |
| "image_id": "frame_{:05d}.jpg".format(idx + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| return img | |
| def draw_aapose( | |
| img, | |
| kp2ds, | |
| threshold=0.6, | |
| data_to_json=None, | |
| idx=-1, | |
| kp2ds_lhand=None, | |
| kp2ds_rhand=None, | |
| draw_hand=False, | |
| stick_width_norm=200, | |
| draw_head=True | |
| ): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| new_kep_list = [ | |
| "Nose", | |
| "Neck", | |
| "RShoulder", | |
| "RElbow", | |
| "RWrist", # No.4 | |
| "LShoulder", | |
| "LElbow", | |
| "LWrist", # No.7 | |
| "RHip", | |
| "RKnee", | |
| "RAnkle", # No.10 | |
| "LHip", | |
| "LKnee", | |
| "LAnkle", # No.13 | |
| "REye", | |
| "LEye", | |
| "REar", | |
| "LEar", | |
| "LToe", | |
| "RToe", | |
| ] | |
| # kp2ds_body = (kp2ds.copy()[[0, 6, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 17, 20]] + \ | |
| # kp2ds.copy()[[0, 5, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 18, 21]]) / 2 | |
| kp2ds = kp2ds.copy() | |
| if not draw_head: | |
| kp2ds[[0,14,15,16,17], 2] = 0 | |
| kp2ds_body = kp2ds | |
| # kp2ds_lhand = kp2ds.copy()[91:112] | |
| # kp2ds_rhand = kp2ds.copy()[112:133] | |
| limbSeq = [ | |
| [2, 3], | |
| [2, 6], # shoulders | |
| [3, 4], | |
| [4, 5], # left arm | |
| [6, 7], | |
| [7, 8], # right arm | |
| [2, 9], | |
| [9, 10], | |
| [10, 11], # right leg | |
| [2, 12], | |
| [12, 13], | |
| [13, 14], # left leg | |
| [2, 1], | |
| [1, 15], | |
| [15, 17], | |
| [1, 16], | |
| [16, 18], # face (nose, eyes, ears) | |
| [14, 19], | |
| [11, 20], # foot | |
| ] | |
| colors = [ | |
| [255, 0, 0], | |
| [255, 85, 0], | |
| [255, 170, 0], | |
| [255, 255, 0], | |
| [170, 255, 0], | |
| [85, 255, 0], | |
| [0, 255, 0], | |
| [0, 255, 85], | |
| [0, 255, 170], | |
| [0, 255, 255], | |
| [0, 170, 255], | |
| [0, 85, 255], | |
| [0, 0, 255], | |
| [85, 0, 255], | |
| [170, 0, 255], | |
| [255, 0, 255], | |
| [255, 0, 170], | |
| [255, 0, 85], | |
| # foot | |
| [200, 200, 0], | |
| [100, 100, 0], | |
| ] | |
| H, W, C = img.shape | |
| stickwidth = max(int(min(H, W) / stick_width_norm), 1) | |
| for _idx, ((k1_index, k2_index), color) in enumerate(zip(limbSeq, colors)): | |
| keypoint1 = kp2ds_body[k1_index - 1] | |
| keypoint2 = kp2ds_body[k2_index - 1] | |
| if keypoint1[-1] < threshold or keypoint2[-1] < threshold: | |
| continue | |
| Y = np.array([keypoint1[0], keypoint2[0]]) | |
| X = np.array([keypoint1[1], keypoint2[1]]) | |
| mX = np.mean(X) | |
| mY = np.mean(Y) | |
| length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
| angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
| polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
| cv2.fillConvexPoly(img, polygon, [int(float(c) * 0.6) for c in color]) | |
| for _idx, (keypoint, color) in enumerate(zip(kp2ds_body, colors)): | |
| if keypoint[-1] < threshold: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| # cv2.circle(canvas, (int(x), int(y)), 4, color, thickness=-1) | |
| cv2.circle(img, (int(x), int(y)), stickwidth, color, thickness=-1) | |
| if draw_hand: | |
| img = draw_handpose(img, kp2ds_lhand, hand_score_th=threshold) | |
| img = draw_handpose(img, kp2ds_rhand, hand_score_th=threshold) | |
| kp2ds_body[:, 0] /= W | |
| kp2ds_body[:, 1] /= H | |
| if data_to_json is not None: | |
| if idx == -1: | |
| data_to_json.append( | |
| { | |
| "image_id": "frame_{:05d}.jpg".format(len(data_to_json) + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| ) | |
| else: | |
| data_to_json[idx] = { | |
| "image_id": "frame_{:05d}.jpg".format(idx + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| return img | |
| def draw_aapose_new( | |
| img, | |
| kp2ds, | |
| threshold=0.6, | |
| data_to_json=None, | |
| idx=-1, | |
| kp2ds_lhand=None, | |
| kp2ds_rhand=None, | |
| draw_hand=False, | |
| stickwidth_type='v2', | |
| draw_head=True | |
| ): | |
| """ | |
| Draw keypoints and connections representing hand pose on a given canvas. | |
| Args: | |
| canvas (np.ndarray): A 3D numpy array representing the canvas (image) on which to draw the hand pose. | |
| keypoints (List[Keypoint]| None): A list of Keypoint objects representing the hand keypoints to be drawn | |
| or None if no keypoints are present. | |
| Returns: | |
| np.ndarray: A 3D numpy array representing the modified canvas with the drawn hand pose. | |
| Note: | |
| The function expects the x and y coordinates of the keypoints to be normalized between 0 and 1. | |
| """ | |
| new_kep_list = [ | |
| "Nose", | |
| "Neck", | |
| "RShoulder", | |
| "RElbow", | |
| "RWrist", # No.4 | |
| "LShoulder", | |
| "LElbow", | |
| "LWrist", # No.7 | |
| "RHip", | |
| "RKnee", | |
| "RAnkle", # No.10 | |
| "LHip", | |
| "LKnee", | |
| "LAnkle", # No.13 | |
| "REye", | |
| "LEye", | |
| "REar", | |
| "LEar", | |
| "LToe", | |
| "RToe", | |
| ] | |
| # kp2ds_body = (kp2ds.copy()[[0, 6, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 17, 20]] + \ | |
| # kp2ds.copy()[[0, 5, 6, 8, 10, 5, 7, 9, 12, 14, 16, 11, 13, 15, 2, 1, 4, 3, 18, 21]]) / 2 | |
| kp2ds = kp2ds.copy() | |
| if not draw_head: | |
| kp2ds[[0,14,15,16,17], 2] = 0 | |
| kp2ds_body = kp2ds | |
| # kp2ds_lhand = kp2ds.copy()[91:112] | |
| # kp2ds_rhand = kp2ds.copy()[112:133] | |
| limbSeq = [ | |
| [2, 3], | |
| [2, 6], # shoulders | |
| [3, 4], | |
| [4, 5], # left arm | |
| [6, 7], | |
| [7, 8], # right arm | |
| [2, 9], | |
| [9, 10], | |
| [10, 11], # right leg | |
| [2, 12], | |
| [12, 13], | |
| [13, 14], # left leg | |
| [2, 1], | |
| [1, 15], | |
| [15, 17], | |
| [1, 16], | |
| [16, 18], # face (nose, eyes, ears) | |
| [14, 19], | |
| [11, 20], # foot | |
| ] | |
| colors = [ | |
| [255, 0, 0], | |
| [255, 85, 0], | |
| [255, 170, 0], | |
| [255, 255, 0], | |
| [170, 255, 0], | |
| [85, 255, 0], | |
| [0, 255, 0], | |
| [0, 255, 85], | |
| [0, 255, 170], | |
| [0, 255, 255], | |
| [0, 170, 255], | |
| [0, 85, 255], | |
| [0, 0, 255], | |
| [85, 0, 255], | |
| [170, 0, 255], | |
| [255, 0, 255], | |
| [255, 0, 170], | |
| [255, 0, 85], | |
| # foot | |
| [200, 200, 0], | |
| [100, 100, 0], | |
| ] | |
| H, W, C = img.shape | |
| H, W, C = img.shape | |
| if stickwidth_type == 'v1': | |
| stickwidth = max(int(min(H, W) / 200), 1) | |
| elif stickwidth_type == 'v2': | |
| stickwidth = max(int(min(H, W) / 200) - 1, 1) | |
| else: | |
| raise | |
| for _idx, ((k1_index, k2_index), color) in enumerate(zip(limbSeq, colors)): | |
| keypoint1 = kp2ds_body[k1_index - 1] | |
| keypoint2 = kp2ds_body[k2_index - 1] | |
| if keypoint1[-1] < threshold or keypoint2[-1] < threshold: | |
| continue | |
| Y = np.array([keypoint1[0], keypoint2[0]]) | |
| X = np.array([keypoint1[1], keypoint2[1]]) | |
| mX = np.mean(X) | |
| mY = np.mean(Y) | |
| length = ((X[0] - X[1]) ** 2 + (Y[0] - Y[1]) ** 2) ** 0.5 | |
| angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1])) | |
| polygon = cv2.ellipse2Poly((int(mY), int(mX)), (int(length / 2), stickwidth), int(angle), 0, 360, 1) | |
| cv2.fillConvexPoly(img, polygon, [int(float(c) * 0.6) for c in color]) | |
| for _idx, (keypoint, color) in enumerate(zip(kp2ds_body, colors)): | |
| if keypoint[-1] < threshold: | |
| continue | |
| x, y = keypoint[0], keypoint[1] | |
| # cv2.circle(canvas, (int(x), int(y)), 4, color, thickness=-1) | |
| cv2.circle(img, (int(x), int(y)), stickwidth, color, thickness=-1) | |
| if draw_hand: | |
| img = draw_handpose_new(img, kp2ds_lhand, stickwidth_type=stickwidth_type, hand_score_th=threshold) | |
| img = draw_handpose_new(img, kp2ds_rhand, stickwidth_type=stickwidth_type, hand_score_th=threshold) | |
| kp2ds_body[:, 0] /= W | |
| kp2ds_body[:, 1] /= H | |
| if data_to_json is not None: | |
| if idx == -1: | |
| data_to_json.append( | |
| { | |
| "image_id": "frame_{:05d}.jpg".format(len(data_to_json) + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| ) | |
| else: | |
| data_to_json[idx] = { | |
| "image_id": "frame_{:05d}.jpg".format(idx + 1), | |
| "height": H, | |
| "width": W, | |
| "category_id": 1, | |
| "keypoints_body": kp2ds_body.tolist(), | |
| "keypoints_left_hand": kp2ds_lhand.tolist(), | |
| "keypoints_right_hand": kp2ds_rhand.tolist(), | |
| } | |
| return img | |
| def draw_bbox(img, bbox, color=(255, 0, 0)): | |
| img = load_image(img) | |
| bbox = [int(bbox_tmp) for bbox_tmp in bbox] | |
| cv2.rectangle(img, (bbox[0], bbox[1]), (bbox[2], bbox[3]), color, 2) | |
| return img | |
| def draw_kp2ds(img, kp2ds, threshold=0, color=(255, 0, 0), skeleton=None, reverse=False): | |
| img = load_image(img, reverse) | |
| if skeleton is not None: | |
| if skeleton == "coco17": | |
| skeleton_list = [ | |
| [6, 8], | |
| [8, 10], | |
| [5, 7], | |
| [7, 9], | |
| [11, 13], | |
| [13, 15], | |
| [12, 14], | |
| [14, 16], | |
| [5, 6], | |
| [6, 12], | |
| [12, 11], | |
| [11, 5], | |
| ] | |
| color_list = [ | |
| (255, 0, 0), | |
| (0, 255, 0), | |
| (0, 0, 255), | |
| (255, 255, 0), | |
| (255, 0, 255), | |
| (0, 255, 255), | |
| ] | |
| elif skeleton == "cocowholebody": | |
| skeleton_list = [ | |
| [6, 8], | |
| [8, 10], | |
| [5, 7], | |
| [7, 9], | |
| [11, 13], | |
| [13, 15], | |
| [12, 14], | |
| [14, 16], | |
| [5, 6], | |
| [6, 12], | |
| [12, 11], | |
| [11, 5], | |
| [15, 17], | |
| [15, 18], | |
| [15, 19], | |
| [16, 20], | |
| [16, 21], | |
| [16, 22], | |
| [91, 92, 93, 94, 95], | |
| [91, 96, 97, 98, 99], | |
| [91, 100, 101, 102, 103], | |
| [91, 104, 105, 106, 107], | |
| [91, 108, 109, 110, 111], | |
| [112, 113, 114, 115, 116], | |
| [112, 117, 118, 119, 120], | |
| [112, 121, 122, 123, 124], | |
| [112, 125, 126, 127, 128], | |
| [112, 129, 130, 131, 132], | |
| ] | |
| color_list = [ | |
| (255, 0, 0), | |
| (0, 255, 0), | |
| (0, 0, 255), | |
| (255, 255, 0), | |
| (255, 0, 255), | |
| (0, 255, 255), | |
| ] | |
| else: | |
| color_list = [color] | |
| for _idx, _skeleton in enumerate(skeleton_list): | |
| for i in range(len(_skeleton) - 1): | |
| cv2.line( | |
| img, | |
| (int(kp2ds[_skeleton[i], 0]), int(kp2ds[_skeleton[i], 1])), | |
| (int(kp2ds[_skeleton[i + 1], 0]), int(kp2ds[_skeleton[i + 1], 1])), | |
| color_list[_idx % len(color_list)], | |
| 3, | |
| ) | |
| for _idx, kp2d in enumerate(kp2ds): | |
| if kp2d[2] > threshold: | |
| cv2.circle(img, (int(kp2d[0]), int(kp2d[1])), 3, color, -1) | |
| # cv2.putText(img, | |
| # str(_idx), | |
| # (int(kp2d[0, i, 0])*1, | |
| # int(kp2d[0, i, 1])*1), | |
| # cv2.FONT_HERSHEY_SIMPLEX, | |
| # 0.75, | |
| # color, | |
| # 2 | |
| # ) | |
| return img | |
| def draw_mask(img, mask, background=0, return_rgba=False): | |
| img = load_image(img) | |
| h, w, _ = img.shape | |
| if type(background) == int: | |
| background = np.ones((h, w, 3)).astype(np.uint8) * 255 * background | |
| backgournd = cv2.resize(background, (w, h)) | |
| img_rgba = np.concatenate([img, mask], -1) | |
| return alphaMerge(img_rgba, background, 0, 0, return_rgba=True) | |
| def draw_pcd(pcd_list, save_path=None): | |
| fig = plt.figure() | |
| ax = fig.add_subplot(111, projection="3d") | |
| color_list = ["r", "g", "b", "y", "p"] | |
| for _idx, _pcd in enumerate(pcd_list): | |
| ax.scatter(_pcd[:, 0], _pcd[:, 1], _pcd[:, 2], c=color_list[_idx], marker="o") | |
| ax.set_xlabel("X") | |
| ax.set_ylabel("Y") | |
| ax.set_zlabel("Z") | |
| if save_path is not None: | |
| plt.savefig(save_path) | |
| else: | |
| plt.savefig("tmp.png") | |
| def load_image(img, reverse=False): | |
| if type(img) == str: | |
| img = cv2.imread(img) | |
| if reverse: | |
| img = img.astype(np.float32) | |
| img = img[:, :, ::-1] | |
| img = img.astype(np.uint8) | |
| return img | |
| def draw_skeleten(meta): | |
| kps = [] | |
| for i, kp in enumerate(meta["keypoints_body"]): | |
| if kp is None: | |
| # if kp is None: | |
| kps.append([0, 0, 0]) | |
| else: | |
| kps.append([*kp, 1]) | |
| kps = np.array(kps) | |
| kps[:, 0] *= meta["width"] | |
| kps[:, 1] *= meta["height"] | |
| pose_img = np.zeros([meta["height"], meta["width"], 3], dtype=np.uint8) | |
| pose_img = draw_aapose( | |
| pose_img, | |
| kps, | |
| draw_hand=True, | |
| kp2ds_lhand=meta["keypoints_left_hand"], | |
| kp2ds_rhand=meta["keypoints_right_hand"], | |
| ) | |
| return pose_img | |
| def draw_skeleten_with_pncc(pncc: np.ndarray, meta: Dict) -> np.ndarray: | |
| """ | |
| Args: | |
| pncc: [H,W,3] | |
| meta: required keys: keypoints_body: [N, 3] keypoints_left_hand, keypoints_right_hand | |
| Return: | |
| np.ndarray [H, W, 3] | |
| """ | |
| # preprocess keypoints | |
| kps = [] | |
| for i, kp in enumerate(meta["keypoints_body"]): | |
| if kp is None: | |
| # if kp is None: | |
| kps.append([0, 0, 0]) | |
| elif i in [14, 15, 16, 17]: | |
| kps.append([0, 0, 0]) | |
| else: | |
| kps.append([*kp]) | |
| kps = np.stack(kps) | |
| kps[:, 0] *= pncc.shape[1] | |
| kps[:, 1] *= pncc.shape[0] | |
| # draw neck | |
| canvas = np.zeros_like(pncc) | |
| if kps[0][2] > 0.6 and kps[1][2] > 0.6: | |
| canvas = draw_ellipse_by_2kp(canvas, kps[0], kps[1], [0, 0, 255]) | |
| # draw pncc | |
| mask = (pncc > 0).max(axis=2) | |
| canvas[mask] = pncc[mask] | |
| pncc = canvas | |
| # draw other skeleten | |
| kps[0] = 0 | |
| meta["keypoints_left_hand"][:, 0] *= meta["width"] | |
| meta["keypoints_left_hand"][:, 1] *= meta["height"] | |
| meta["keypoints_right_hand"][:, 0] *= meta["width"] | |
| meta["keypoints_right_hand"][:, 1] *= meta["height"] | |
| pose_img = draw_aapose( | |
| pncc, | |
| kps, | |
| draw_hand=True, | |
| kp2ds_lhand=meta["keypoints_left_hand"], | |
| kp2ds_rhand=meta["keypoints_right_hand"], | |
| ) | |
| return pose_img | |
| FACE_CUSTOM_STYLE = { | |
| "eyeball": {"indexs": [68, 69], "color": [255, 255, 255], "connect": False}, | |
| "left_eyebrow": {"indexs": [17, 18, 19, 20, 21], "color": [0, 255, 0]}, | |
| "right_eyebrow": {"indexs": [22, 23, 24, 25, 26], "color": [0, 0, 255]}, | |
| "left_eye": {"indexs": [36, 37, 38, 39, 40, 41], "color": [255, 255, 0], "close": True}, | |
| "right_eye": {"indexs": [42, 43, 44, 45, 46, 47], "color": [255, 0, 255], "close": True}, | |
| "mouth_outside": {"indexs": list(range(48, 60)), "color": [100, 255, 50], "close": True}, | |
| "mouth_inside": {"indexs": [60, 61, 62, 63, 64, 65, 66, 67], "color": [255, 100, 50], "close": True}, | |
| } | |
| def draw_face_kp(img, kps, thickness=2, style=FACE_CUSTOM_STYLE): | |
| """ | |
| Args: | |
| img: [H, W, 3] | |
| kps: [70, 2] | |
| """ | |
| img = img.copy() | |
| for key, item in style.items(): | |
| pts = np.array(kps[item["indexs"]]).astype(np.int32) | |
| connect = item.get("connect", True) | |
| color = item["color"] | |
| close = item.get("close", False) | |
| if connect: | |
| cv2.polylines(img, [pts], close, color, thickness=thickness) | |
| else: | |
| for kp in pts: | |
| kp = np.array(kp).astype(np.int32) | |
| cv2.circle(img, kp, thickness * 2, color=color, thickness=-1) | |
| return img | |
| def draw_traj(metas: List[AAPoseMeta], threshold=0.6): | |
| colors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0], [85, 255, 0], [0, 255, 0], \ | |
| [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], \ | |
| [170, 0, 255], [255, 0, 255], [255, 0, 170], [255, 0, 85], [100, 255, 50], [255, 100, 50], | |
| # foot | |
| [200, 200, 0], | |
| [100, 100, 0] | |
| ] | |
| limbSeq = [ | |
| [1, 2], [1, 5], # shoulders | |
| [2, 3], [3, 4], # left arm | |
| [5, 6], [6, 7], # right arm | |
| [1, 8], [8, 9], [9, 10], # right leg | |
| [1, 11], [11, 12], [12, 13], # left leg | |
| # face (nose, eyes, ears) | |
| [13, 18], [10, 19] # foot | |
| ] | |
| face_seq = [[1, 0], [0, 14], [14, 16], [0, 15], [15, 17]] | |
| kp_body = np.array([meta.kps_body for meta in metas]) | |
| kp_body_p = np.array([meta.kps_body_p for meta in metas]) | |
| face_seq = random.sample(face_seq, 2) | |
| kp_lh = np.array([meta.kps_lhand for meta in metas]) | |
| kp_rh = np.array([meta.kps_rhand for meta in metas]) | |
| kp_lh_p = np.array([meta.kps_lhand_p for meta in metas]) | |
| kp_rh_p = np.array([meta.kps_rhand_p for meta in metas]) | |
| # kp_lh = np.concatenate([kp_lh, kp_lh_p], axis=-1) | |
| # kp_rh = np.concatenate([kp_rh, kp_rh_p], axis=-1) | |
| new_limbSeq = [] | |
| key_point_list = [] | |
| for _idx, ((k1_index, k2_index)) in enumerate(limbSeq): | |
| vis = (kp_body_p[:, k1_index] > threshold) * (kp_body_p[:, k2_index] > threshold) * 1 | |
| if vis.sum() * 1.0 / vis.shape[0] > 0.4: | |
| new_limbSeq.append([k1_index, k2_index]) | |
| for _idx, ((k1_index, k2_index)) in enumerate(limbSeq): | |
| keypoint1 = kp_body[:, k1_index - 1] | |
| keypoint2 = kp_body[:, k2_index - 1] | |
| interleave = random.randint(4, 7) | |
| randind = random.randint(0, interleave - 1) | |
| # randind = random.rand(range(interleave), sampling_num) | |
| Y = np.array([keypoint1[:, 0], keypoint2[:, 0]]) | |
| X = np.array([keypoint1[:, 1], keypoint2[:, 1]]) | |
| vis = (keypoint1[:, -1] > threshold) * (keypoint2[:, -1] > threshold) * 1 | |
| # for randidx in randind: | |
| t = randind / interleave | |
| x = (1-t)*Y[0, :] + t*Y[1, :] | |
| y = (1-t)*X[0, :] + t*X[1, :] | |
| # np.array([1]) | |
| x = x.astype(int) | |
| y = y.astype(int) | |
| new_array = np.array([x, y, vis]).T | |
| key_point_list.append(new_array) | |
| indx_lh = random.randint(0, kp_lh.shape[1] - 1) | |
| lh = kp_lh[:, indx_lh, :] | |
| lh_p = kp_lh_p[:, indx_lh:indx_lh+1] | |
| lh = np.concatenate([lh, lh_p], axis=-1) | |
| indx_rh = random.randint(0, kp_rh.shape[1] - 1) | |
| rh = kp_rh[:, random.randint(0, kp_rh.shape[1] - 1), :] | |
| rh_p = kp_rh_p[:, indx_rh:indx_rh+1] | |
| rh = np.concatenate([rh, rh_p], axis=-1) | |
| lh[-1, :] = (lh[-1, :] > threshold) * 1 | |
| rh[-1, :] = (rh[-1, :] > threshold) * 1 | |
| # print(rh.shape, new_array.shape) | |
| # exit() | |
| key_point_list.append(lh.astype(int)) | |
| key_point_list.append(rh.astype(int)) | |
| key_points_list = np.stack(key_point_list) | |
| num_points = len(key_points_list) | |
| sample_colors = random.sample(colors, num_points) | |
| stickwidth = max(int(min(metas[0].width, metas[0].height) / 150), 2) | |
| image_list_ori = [] | |
| for i in range(key_points_list.shape[-2]): | |
| _image_vis = np.zeros((metas[0].width, metas[0].height, 3)) | |
| points = key_points_list[:, i, :] | |
| for idx, point in enumerate(points): | |
| x, y, vis = point | |
| if vis == 1: | |
| cv2.circle(_image_vis, (x, y), stickwidth, sample_colors[idx], thickness=-1) | |
| image_list_ori.append(_image_vis) | |
| return image_list_ori | |
| return [np.zeros([meta.width, meta.height, 3], dtype=np.uint8) for meta in metas] | |
| if __name__ == "__main__": | |
| meta = { | |
| "image_id": "00472.jpg", | |
| "height": 540, | |
| "width": 414, | |
| "category_id": 1, | |
| "keypoints_body": [ | |
| [0.5084776947463768, 0.11350188078703703], | |
| [0.504467655495169, 0.20419560185185184], | |
| [0.3982016153381642, 0.198046875], | |
| [0.3841664779589372, 0.34869068287037036], | |
| [0.3901815368357488, 0.4670536747685185], | |
| [0.610733695652174, 0.2103443287037037], | |
| [0.6167487545289855, 0.3517650462962963], | |
| [0.6448190292874396, 0.4762767650462963], | |
| [0.4523371452294686, 0.47320240162037036], | |
| [0.4503321256038647, 0.6776475694444445], | |
| [0.47639738073671495, 0.8544234664351852], | |
| [0.5766483620169082, 0.47320240162037036], | |
| [0.5666232638888888, 0.6761103877314815], | |
| [0.534542949879227, 0.863646556712963], | |
| [0.4864224788647343, 0.09505570023148148], | |
| [0.5285278910024155, 0.09351851851851851], | |
| [0.46236224335748793, 0.10581597222222222], | |
| [0.5586031853864735, 0.10274160879629629], | |
| [0.4994551064311594, 0.9405056423611111], | |
| [0.4152442821557971, 0.9312825520833333], | |
| ], | |
| "keypoints_left_hand": [ | |
| [267.78515625, 263.830078125, 1.2840936183929443], | |
| [265.294921875, 269.640625, 1.2546794414520264], | |
| [263.634765625, 277.111328125, 1.2863062620162964], | |
| [262.8046875, 285.412109375, 1.267038345336914], | |
| [261.14453125, 292.8828125, 1.280144453048706], | |
| [273.595703125, 281.26171875, 1.2592815160751343], | |
| [271.10546875, 291.22265625, 1.3256099224090576], | |
| [265.294921875, 294.54296875, 1.2368024587631226], | |
| [261.14453125, 294.54296875, 0.9771889448165894], | |
| [274.42578125, 282.091796875, 1.250044584274292], | |
| [269.4453125, 291.22265625, 1.2571144104003906], | |
| [264.46484375, 292.8828125, 1.177802324295044], | |
| [260.314453125, 292.052734375, 0.9283463358879089], | |
| [273.595703125, 282.091796875, 1.1834490299224854], | |
| [269.4453125, 290.392578125, 1.188171625137329], | |
| [265.294921875, 290.392578125, 1.192609429359436], | |
| [261.974609375, 289.5625, 0.9366656541824341], | |
| [271.935546875, 281.26171875, 1.0946396589279175], | |
| [268.615234375, 287.072265625, 0.9906131029129028], | |
| [265.294921875, 287.90234375, 1.0219476222991943], | |
| [262.8046875, 287.072265625, 0.9240120053291321], | |
| ], | |
| "keypoints_right_hand": [ | |
| [161.53515625, 258.849609375, 1.2069408893585205], | |
| [168.17578125, 263.0, 1.1846840381622314], | |
| [173.986328125, 269.640625, 1.1435924768447876], | |
| [173.986328125, 277.94140625, 1.1802611351013184], | |
| [173.986328125, 286.2421875, 1.2599592208862305], | |
| [165.685546875, 275.451171875, 1.0633569955825806], | |
| [167.345703125, 286.2421875, 1.1693341732025146], | |
| [169.8359375, 291.22265625, 1.2698509693145752], | |
| [170.666015625, 294.54296875, 1.0619274377822876], | |
| [160.705078125, 276.28125, 1.0995020866394043], | |
| [163.1953125, 287.90234375, 1.2735884189605713], | |
| [166.515625, 291.22265625, 1.339503526687622], | |
| [169.005859375, 294.54296875, 1.0835273265838623], | |
| [157.384765625, 277.111328125, 1.0866981744766235], | |
| [161.53515625, 287.072265625, 1.2468621730804443], | |
| [164.025390625, 289.5625, 1.2817761898040771], | |
| [166.515625, 292.052734375, 1.099466323852539], | |
| [155.724609375, 277.111328125, 1.1065717935562134], | |
| [159.044921875, 285.412109375, 1.1924479007720947], | |
| [160.705078125, 287.072265625, 1.1304771900177002], | |
| [162.365234375, 287.90234375, 1.0040509700775146], | |
| ], | |
| } | |
| demo_meta = AAPoseMeta(meta) | |
| res = draw_traj([demo_meta]*5) | |
| cv2.imwrite("traj.png", res[0][..., ::-1]) | |