Buckets:
| import cv2 | |
| import numpy as np | |
| from .skeleton import KP21_BONES | |
| def to_camera(points, camera): | |
| rotation, position = camera[:, :3, :3], camera[:, :3, 3] | |
| return np.einsum("tji,tkj->tki", rotation, points - position[:, None]) | |
| def procrustes(source, target): | |
| source_mean, target_mean = source.mean(axis=0), target.mean(axis=0) | |
| a, b = source - source_mean, target - target_mean | |
| u, s, vt = np.linalg.svd(a.T @ b) | |
| sign = np.sign(np.linalg.det(u @ vt)) | |
| rotation = u @ np.diag([1.0, 1.0, sign]) @ vt | |
| scale = (s * [1.0, 1.0, sign]).sum() / (a**2).sum() | |
| return scale * a @ rotation + target_mean | |
| def keypoint_errors(predicted, reference, valid): | |
| errors = {"absolute": [], "root_relative": [], "aligned": []} | |
| for t in np.where(valid)[0]: | |
| p, r = predicted[t], reference[t] | |
| errors["absolute"].append(np.linalg.norm(p - r, axis=-1).mean()) | |
| errors["root_relative"].append( | |
| np.linalg.norm((p - p[0]) - (r - r[0]), axis=-1).mean() | |
| ) | |
| errors["aligned"].append(np.linalg.norm(procrustes(p, r) - r, axis=-1).mean()) | |
| return {name: 1000 * float(np.mean(values)) for name, values in errors.items()} | |
| def draw_skeleton(image, keypoints, intrinsics, color, scale=1.0): | |
| if keypoints[:, 2].min() <= 0.01: | |
| return | |
| projected = keypoints @ intrinsics.T | |
| projected = projected[:, :2] / projected[:, 2:3] * scale | |
| points = projected.astype(int) | |
| for a, b in KP21_BONES: | |
| cv2.line(image, tuple(points[a]), tuple(points[b]), color, 2, cv2.LINE_AA) | |
| for point in points: | |
| cv2.circle(image, tuple(point), 3, color, -1, cv2.LINE_AA) | |
Xet Storage Details
- Size:
- 1.64 kB
- Xet hash:
- 311dd4d45f23fb58d9e13413f37fe9b0b076285b46b52e8d331e5582d3fde98a
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.