Spaces:
Runtime error
Runtime error
| import math | |
| import cv2 | |
| import numpy as np | |
| IMG_SIZE = (288, 384) | |
| MEAN = np.array([0.485, 0.456, 0.406]) | |
| STD = np.array([0.229, 0.224, 0.225]) | |
| KPS = ( | |
| "Head", | |
| "Neck", | |
| "Right Shoulder", | |
| "Right Arm", | |
| "Right Hand", | |
| "Left Shoulder", | |
| "Left Arm", | |
| "Left Hand", | |
| "Spine", | |
| "Hips", | |
| "Right Upper Leg", | |
| "Right Leg", | |
| "Right Foot", | |
| "Left Upper Leg", | |
| "Left Leg", | |
| "Left Foot", | |
| "Left Toe", | |
| "Right Toe", | |
| ) | |
| SKELETON = ( | |
| (0, 1), | |
| (1, 8), | |
| (8, 9), | |
| (9, 10), | |
| (9, 13), | |
| (10, 11), | |
| (11, 12), | |
| (13, 14), | |
| (14, 15), | |
| (1, 2), | |
| (2, 3), | |
| (3, 4), | |
| (1, 5), | |
| (5, 6), | |
| (6, 7), | |
| (15, 16), | |
| (12, 17), | |
| ) | |
| OPENPOSE_TO_GESTURE = ( | |
| 0, # 0 Head\n", | |
| 1, # Neck\n", | |
| 2, # 2 Right Shoulder\n", | |
| 3, # Right Arm\n", | |
| 4, # 4 Right Hand\n", | |
| 5, # Left Shoulder\n", | |
| 6, # 6 Left Arm\n", | |
| 7, # Left Hand\n", | |
| 9, # 8 Hips\n", | |
| 10, # Right Upper Leg\n", | |
| 11, # 10Right Leg\n", | |
| 12, # Right Foot\n", | |
| 13, # 12Left Upper Leg\n", | |
| 14, # Left Leg\n", | |
| 15, # 14Left Foot\n", | |
| -1, # \n", | |
| -1, # 16\n", | |
| -1, # \n", | |
| -1, # 18\n", | |
| 16, # Left Toe\n", | |
| -1, # 20\n", | |
| -1, # \n", | |
| 17, # 22Right Toe\n", | |
| -1, # \n", | |
| -1, # 24\n", | |
| ) | |
| def transform(img): | |
| img = img.astype("float32") / 255 | |
| img = (img - MEAN) / STD | |
| return np.transpose(img, axes=(2, 0, 1)) | |
| def get_affine_transform( | |
| center, | |
| scale, | |
| rot, | |
| output_size, | |
| shift=np.array([0, 0], dtype=np.float32), | |
| inv=0, | |
| pixel_std=200, | |
| ): | |
| if not isinstance(scale, np.ndarray) and not isinstance(scale, list): | |
| scale = np.array([scale, scale]) | |
| scale_tmp = scale * pixel_std | |
| src_w = scale_tmp[0] | |
| dst_w = output_size[0] | |
| dst_h = output_size[1] | |
| rot_rad = np.pi * rot / 180 | |
| src_dir = get_dir([0, src_w * -0.5], rot_rad) | |
| dst_dir = np.array([0, dst_w * -0.5], np.float32) | |
| src = np.zeros((3, 2), dtype=np.float32) | |
| dst = np.zeros((3, 2), dtype=np.float32) | |
| src[0, :] = center + scale_tmp * shift | |
| src[1, :] = center + src_dir + scale_tmp * shift | |
| dst[0, :] = [dst_w * 0.5, dst_h * 0.5] | |
| dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir | |
| src[2:, :] = get_3rd_point(src[0, :], src[1, :]) | |
| dst[2:, :] = get_3rd_point(dst[0, :], dst[1, :]) | |
| if inv: | |
| trans = cv2.getAffineTransform(np.float32(dst), np.float32(src)) | |
| else: | |
| trans = cv2.getAffineTransform(np.float32(src), np.float32(dst)) | |
| return trans | |
| def get_3rd_point(a, b): | |
| direct = a - b | |
| return b + np.array([-direct[1], direct[0]], dtype=np.float32) | |
| def get_dir(src_point, rot_rad): | |
| sn, cs = np.sin(rot_rad), np.cos(rot_rad) | |
| src_result = [0, 0] | |
| src_result[0] = src_point[0] * cs - src_point[1] * sn | |
| src_result[1] = src_point[0] * sn + src_point[1] * cs | |
| return src_result | |
| def process_image(path, input_img_size, pixel_std=200): | |
| data_numpy = cv2.imread(path, cv2.IMREAD_COLOR | cv2.IMREAD_IGNORE_ORIENTATION) | |
| # BUG HERE. Must be uncommented | |
| # data_numpy = cv2.cvtColor(data_numpy, cv2.COLOR_BGR2RGB) | |
| h, w = data_numpy.shape[:2] | |
| c = np.array([w / 2, h / 2], dtype=np.float32) | |
| aspect_ratio = input_img_size[0] / input_img_size[1] | |
| if w > aspect_ratio * h: | |
| h = w * 1.0 / aspect_ratio | |
| elif w < aspect_ratio * h: | |
| w = h * aspect_ratio | |
| s = np.array([w / pixel_std, h / pixel_std], dtype=np.float32) * 1.25 | |
| r = 0 | |
| trans = get_affine_transform(c, s, r, input_img_size, pixel_std=pixel_std) | |
| input = cv2.warpAffine(data_numpy, trans, input_img_size, flags=cv2.INTER_LINEAR) | |
| input = transform(input) | |
| return input, data_numpy, c, s | |
| def get_final_preds(batch_heatmaps, center, scale, post_process=False): | |
| coords, maxvals = get_max_preds(batch_heatmaps) | |
| heatmap_height = batch_heatmaps.shape[2] | |
| heatmap_width = batch_heatmaps.shape[3] | |
| # post-processing | |
| if post_process: | |
| for n in range(coords.shape[0]): | |
| for p in range(coords.shape[1]): | |
| hm = batch_heatmaps[n][p] | |
| px = int(math.floor(coords[n][p][0] + 0.5)) | |
| py = int(math.floor(coords[n][p][1] + 0.5)) | |
| if 1 < px < heatmap_width - 1 and 1 < py < heatmap_height - 1: | |
| diff = np.array( | |
| [ | |
| hm[py][px + 1] - hm[py][px - 1], | |
| hm[py + 1][px] - hm[py - 1][px], | |
| ] | |
| ) | |
| coords[n][p] += np.sign(diff) * 0.25 | |
| preds = coords.copy() | |
| # Transform back | |
| for i in range(coords.shape[0]): | |
| preds[i] = transform_preds( | |
| coords[i], center[i], scale[i], [heatmap_width, heatmap_height] | |
| ) | |
| return preds, maxvals | |
| def transform_preds(coords, center, scale, output_size): | |
| target_coords = np.zeros(coords.shape) | |
| trans = get_affine_transform(center, scale, 0, output_size, inv=1) | |
| for p in range(coords.shape[0]): | |
| target_coords[p, 0:2] = affine_transform(coords[p, 0:2], trans) | |
| return target_coords | |
| def affine_transform(pt, t): | |
| new_pt = np.array([pt[0], pt[1], 1.0]).T | |
| new_pt = np.dot(t, new_pt) | |
| return new_pt[:2] | |
| def get_max_preds(batch_heatmaps): | |
| """ | |
| get predictions from score maps | |
| heatmaps: numpy.ndarray([batch_size, num_joints, height, width]) | |
| """ | |
| assert isinstance( | |
| batch_heatmaps, np.ndarray | |
| ), "batch_heatmaps should be numpy.ndarray" | |
| assert batch_heatmaps.ndim == 4, "batch_images should be 4-ndim" | |
| batch_size = batch_heatmaps.shape[0] | |
| num_joints = batch_heatmaps.shape[1] | |
| width = batch_heatmaps.shape[3] | |
| heatmaps_reshaped = batch_heatmaps.reshape((batch_size, num_joints, -1)) | |
| idx = np.argmax(heatmaps_reshaped, 2) | |
| maxvals = np.amax(heatmaps_reshaped, 2) | |
| maxvals = maxvals.reshape((batch_size, num_joints, 1)) | |
| idx = idx.reshape((batch_size, num_joints, 1)) | |
| preds = np.tile(idx, (1, 1, 2)).astype(np.float32) | |
| preds[:, :, 0] = (preds[:, :, 0]) % width | |
| preds[:, :, 1] = np.floor((preds[:, :, 1]) / width) | |
| pred_mask = np.tile(np.greater(maxvals, 0.0), (1, 1, 2)) | |
| pred_mask = pred_mask.astype(np.float32) | |
| preds *= pred_mask | |
| return preds, maxvals | |
| def infer_single_image(model, img_path, input_img_size=(288, 384), return_kps=True): | |
| img_path = str(img_path) | |
| pose_input, img, center, scale = process_image( | |
| img_path, input_img_size=input_img_size | |
| ) | |
| model.setInput(pose_input[None]) | |
| predicted_heatmap = model.forward() | |
| if not return_kps: | |
| return predicted_heatmap.squeeze(0) | |
| predicted_keypoints, confidence = get_final_preds( | |
| predicted_heatmap, center[None], scale[None], post_process=True | |
| ) | |
| (predicted_keypoints, confidence, predicted_heatmap,) = ( | |
| predicted_keypoints.squeeze(0), | |
| confidence.squeeze(0), | |
| predicted_heatmap.squeeze(0), | |
| ) | |
| return img, predicted_keypoints, confidence, predicted_heatmap | |