Calculate the mean per-joint position error (MPJPE) and the error after rigid alignment with the ground truth (PA-MPJPE). batch_size: N num_keypoints: K keypoint_dims: C Args: pred (np.ndarray[N, K, C]): Predicted keypoint location. gt (np.ndarray[N, K, C]): Groun
(pred, gt, mask, alignment='none')
| 7 | |
| 8 | |
| 9 | def keypoint_mpjpe(pred, gt, mask, alignment='none'): |
| 10 | """Calculate the mean per-joint position error (MPJPE) and the error after |
| 11 | rigid alignment with the ground truth (PA-MPJPE). |
| 12 | batch_size: N |
| 13 | num_keypoints: K |
| 14 | keypoint_dims: C |
| 15 | Args: |
| 16 | pred (np.ndarray[N, K, C]): Predicted keypoint location. |
| 17 | gt (np.ndarray[N, K, C]): Groundtruth keypoint location. |
| 18 | mask (np.ndarray[N, K]): Visibility of the target. False for invisible |
| 19 | joints, and True for visible. Invisible joints will be ignored for |
| 20 | accuracy calculation. |
| 21 | alignment (str, optional): method to align the prediction with the |
| 22 | groundtruth. Supported options are: |
| 23 | - ``'none'``: no alignment will be applied |
| 24 | - ``'scale'``: align in the least-square sense in scale |
| 25 | - ``'procrustes'``: align in the least-square sense in scale, |
| 26 | rotation and translation. |
| 27 | Returns: |
| 28 | tuple: A tuple containing joint position errors |
| 29 | - mpjpe (float|np.ndarray[N]): mean per-joint position error. |
| 30 | - pa-mpjpe (float|np.ndarray[N]): mpjpe after rigid alignment with the |
| 31 | ground truth |
| 32 | """ |
| 33 | assert mask.any() |
| 34 | |
| 35 | if alignment == 'none': |
| 36 | pass |
| 37 | elif alignment == 'procrustes': |
| 38 | pred = np.stack([ |
| 39 | compute_similarity_transform(pred_i, gt_i) |
| 40 | for pred_i, gt_i in zip(pred, gt) |
| 41 | ]) |
| 42 | elif alignment == 'scale': |
| 43 | pred_dot_pred = np.einsum('nkc,nkc->n', pred, pred) |
| 44 | pred_dot_gt = np.einsum('nkc,nkc->n', pred, gt) |
| 45 | scale_factor = pred_dot_gt / pred_dot_pred |
| 46 | pred = pred * scale_factor[:, None, None] |
| 47 | else: |
| 48 | raise ValueError(f'Invalid value for alignment: {alignment}') |
| 49 | |
| 50 | error = np.linalg.norm(pred - gt, ord=2, axis=-1)[mask].mean() |
| 51 | |
| 52 | return error |
| 53 | |
| 54 | |
| 55 | def keypoint_accel_error(gt, pred, mask=None): |
no test coverage detected