| import os |
| import cv2 |
| import torch |
| import uuid |
| import trimesh |
| import numpy as np |
| import matplotlib.cm as cm |
|
|
| from mediapipe import solutions |
| from mediapipe.framework.formats import landmark_pb2 |
|
|
| from lib.core.config import cfg |
| from lib.utils.human_models import mano |
| from lib.utils.mano_utils import change_flat_hand_mean |
|
|
|
|
|
|
| class ContactRenderer: |
| def __init__(self): |
| self.default_mesh_color = [130, 130, 130, 255] |
| self.contact_mesh_color = [0, 255, 0, 255] |
| |
| with torch.no_grad(): |
| hand_pose = change_flat_hand_mean(np.zeros((48)), remove=True) |
| mano_rest_out = mano.layer['right'](betas=torch.zeros((1, 10)), hand_pose=torch.from_numpy(hand_pose[None, 3:]).float(), global_orient=torch.zeros((1, 3)), transl=torch.zeros((1, 3))) |
| self.hand_model_mano = trimesh.Trimesh(mano_rest_out.vertices[0], mano.watertight_face['right']) |
|
|
| def export_contact_mesh(self, contact_mask, output_path=None): |
| vis_contact = contact_mask == 1.0 |
| self.hand_model_mano.visual.vertex_colors = np.tile(self.default_mesh_color, (self.hand_model_mano.vertices.shape[0], 1)) |
| self.hand_model_mano.visual.vertex_colors[vis_contact] = self.contact_mesh_color |
| if output_path is None: |
| output_path = f"/tmp/contact_mesh_{uuid.uuid4().hex}.obj" |
| self.hand_model_mano.export(output_path) |
| return output_path |
|
|
|
|
| |
| MARGIN = 10 |
| FONT_SIZE = 1 |
| FONT_THICKNESS = 1 |
| HANDEDNESS_TEXT_COLOR = (88, 205, 54) |
|
|
|
|
| def draw_landmarks_on_image(rgb_image, detection_result): |
| hand_landmarks_list = detection_result.hand_landmarks |
| handedness_list = detection_result.handedness |
| annotated_image = np.copy(rgb_image) |
| right_hand_bbox = None |
|
|
| best_score = -1.0 |
| best_idx = -1 |
|
|
| |
| for idx in range(len(hand_landmarks_list)): |
| handedness = handedness_list[idx][0] |
| if handedness.category_name == "Right" and handedness.score > best_score: |
| best_score = handedness.score |
| best_idx = idx |
|
|
| |
| if best_idx != -1: |
| hand_landmarks = hand_landmarks_list[best_idx] |
| handedness = handedness_list[best_idx] |
|
|
| |
| hand_landmarks_proto = landmark_pb2.NormalizedLandmarkList() |
| hand_landmarks_proto.landmark.extend([ |
| landmark_pb2.NormalizedLandmark(x=lm.x, y=lm.y, z=lm.z) for lm in hand_landmarks |
| ]) |
| solutions.drawing_utils.draw_landmarks( |
| annotated_image, |
| hand_landmarks_proto, |
| solutions.hands.HAND_CONNECTIONS, |
| solutions.drawing_styles.get_default_hand_landmarks_style(), |
| solutions.drawing_styles.get_default_hand_connections_style()) |
|
|
| |
| height, width, _ = annotated_image.shape |
| x_coords = [lm.x * width for lm in hand_landmarks] |
| y_coords = [lm.y * height for lm in hand_landmarks] |
| x_min, x_max = int(min(x_coords)), int(max(x_coords)) |
| y_min, y_max = int(min(y_coords)), int(max(y_coords)) |
| bb_c_x, bb_c_y = (x_min+x_max)/2, (y_min+y_max)/2 |
| bb_width, bb_height = x_max-x_min, y_max-y_min |
|
|
| expand_ratio = cfg.DATASET.ho_big_bbox_expand_ratio |
|
|
| bb_width_expand, bb_height_expand = expand_ratio * bb_width, expand_ratio * bb_height |
| x_min_expand, y_min_expand = bb_c_x - 0.5 * bb_width_expand, bb_c_y - 0.5 * bb_height_expand |
| |
| right_hand_bbox = [x_min_expand, y_min_expand, bb_width_expand, bb_height_expand] |
|
|
| |
| cv2.rectangle(annotated_image, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2) |
| cv2.putText(annotated_image, "Right Hand", (x_min, y_min - MARGIN), |
| cv2.FONT_HERSHEY_DUPLEX, FONT_SIZE, HANDEDNESS_TEXT_COLOR, FONT_THICKNESS, cv2.LINE_AA) |
|
|
| return annotated_image, right_hand_bbox |
|
|
|
|
| def draw_landmarks_on_image_simple(rgb_image, right_hand_bbox): |
| |
| annotated_image = rgb_image.copy()[..., ::-1] |
| annotated_image = np.ascontiguousarray(annotated_image) |
|
|
| |
| x_min, x_max = int(right_hand_bbox[0]), int(right_hand_bbox[0]+right_hand_bbox[2]) |
| y_min, y_max = int(right_hand_bbox[1]), int(right_hand_bbox[1]+right_hand_bbox[3]) |
| bb_c_x, bb_c_y = (x_min+x_max)/2, (y_min+y_max)/2 |
| bb_width, bb_height = x_max-x_min, y_max-y_min |
|
|
| expand_ratio = cfg.DATASET.ho_big_bbox_expand_ratio |
|
|
| bb_width_expand, bb_height_expand = expand_ratio * bb_width, expand_ratio * bb_height |
| x_min_expand, y_min_expand = bb_c_x - 0.5 * bb_width_expand, bb_c_y - 0.5 * bb_height_expand |
| |
| right_hand_bbox = [x_min_expand, y_min_expand, bb_width_expand, bb_height_expand] |
|
|
| x_min, y_min, x_max, y_max = int(right_hand_bbox[0]), int(right_hand_bbox[1]), int(right_hand_bbox[0]+right_hand_bbox[2]), int(right_hand_bbox[1]+right_hand_bbox[3]) |
| cv2.rectangle(annotated_image, (x_min, y_min), (x_max, y_max), (0, 255, 0), 2) |
| cv2.putText(annotated_image, "Right Hand", (x_min, y_min - MARGIN), cv2.FONT_HERSHEY_DUPLEX, FONT_SIZE, HANDEDNESS_TEXT_COLOR, FONT_THICKNESS, cv2.LINE_AA) |
|
|
| return annotated_image, right_hand_bbox |