Calculate the Percentage of Correct Keypoints (3DPCK) w. or w/o rigid alignment. Paper ref: `Monocular 3D Human Pose Estimation In The Wild Using Improved CNN Supervision' 3DV'2017. `__ . Note: - batch_size: N - num_keypoints: K
(pred, gt, mask, alignment='none', threshold=150.)
| 117 | |
| 118 | |
| 119 | def keypoint_3d_pck(pred, gt, mask, alignment='none', threshold=150.): |
| 120 | """Calculate the Percentage of Correct Keypoints (3DPCK) w. or w/o rigid |
| 121 | alignment. |
| 122 | Paper ref: `Monocular 3D Human Pose Estimation In The Wild Using Improved |
| 123 | CNN Supervision' 3DV'2017. <https://arxiv.org/pdf/1611.09813>`__ . |
| 124 | Note: |
| 125 | - batch_size: N |
| 126 | - num_keypoints: K |
| 127 | - keypoint_dims: C |
| 128 | Args: |
| 129 | pred (np.ndarray[N, K, C]): Predicted keypoint location. |
| 130 | gt (np.ndarray[N, K, C]): Groundtruth keypoint location. |
| 131 | mask (np.ndarray[N, K]): Visibility of the target. False for invisible |
| 132 | joints, and True for visible. Invisible joints will be ignored for |
| 133 | accuracy calculation. |
| 134 | alignment (str, optional): method to align the prediction with the |
| 135 | groundtruth. Supported options are: |
| 136 | - ``'none'``: no alignment will be applied |
| 137 | - ``'scale'``: align in the least-square sense in scale |
| 138 | - ``'procrustes'``: align in the least-square sense in scale, |
| 139 | rotation and translation. |
| 140 | threshold: If L2 distance between the prediction and the groundtruth |
| 141 | is less then threshold, the predicted result is considered as |
| 142 | correct. Default: 150 (mm). |
| 143 | Returns: |
| 144 | pck: percentage of correct keypoints. |
| 145 | """ |
| 146 | assert mask.any() |
| 147 | |
| 148 | if alignment == 'none': |
| 149 | pass |
| 150 | elif alignment == 'procrustes': |
| 151 | pred = np.stack([ |
| 152 | compute_similarity_transform(pred_i, gt_i) |
| 153 | for pred_i, gt_i in zip(pred, gt) |
| 154 | ]) |
| 155 | elif alignment == 'scale': |
| 156 | pred_dot_pred = np.einsum('nkc,nkc->n', pred, pred) |
| 157 | pred_dot_gt = np.einsum('nkc,nkc->n', pred, gt) |
| 158 | scale_factor = pred_dot_gt / pred_dot_pred |
| 159 | pred = pred * scale_factor[:, None, None] |
| 160 | else: |
| 161 | raise ValueError(f'Invalid value for alignment: {alignment}') |
| 162 | |
| 163 | error = np.linalg.norm(pred - gt, ord=2, axis=-1) |
| 164 | pck = (error < threshold).astype(np.float32)[mask].mean() * 100 |
| 165 | |
| 166 | return pck |
| 167 | |
| 168 | |
| 169 | def keypoint_3d_auc(pred, gt, mask, alignment='none'): |
no test coverage detected