Project points in camera coordinates to image coordinates. Args: points_3d (Tensor or np.ndarray): Points in shape (N, 3). proj_mat (Tensor or np.ndarray): Transformation matrix between coordinates. with_depth (bool): Whether to keep depth in the output.
(points_3d: Union[Tensor, np.ndarray],
proj_mat: Union[Tensor, np.ndarray],
with_depth: bool = False)
| 242 | |
| 243 | @array_converter(apply_to=('points_3d', 'proj_mat')) |
| 244 | def points_cam2img(points_3d: Union[Tensor, np.ndarray], |
| 245 | proj_mat: Union[Tensor, np.ndarray], |
| 246 | with_depth: bool = False) -> Union[Tensor, np.ndarray]: |
| 247 | """Project points in camera coordinates to image coordinates. |
| 248 | |
| 249 | Args: |
| 250 | points_3d (Tensor or np.ndarray): Points in shape (N, 3). |
| 251 | proj_mat (Tensor or np.ndarray): Transformation matrix between |
| 252 | coordinates. |
| 253 | with_depth (bool): Whether to keep depth in the output. |
| 254 | Defaults to False. |
| 255 | |
| 256 | Returns: |
| 257 | Tensor or np.ndarray: Points in image coordinates with shape [N, 2] if |
| 258 | ``with_depth=False``, else [N, 3]. |
| 259 | """ |
| 260 | points_shape = list(points_3d.shape) |
| 261 | points_shape[-1] = 1 |
| 262 | |
| 263 | assert len(proj_mat.shape) == 2, \ |
| 264 | 'The dimension of the projection matrix should be 2 ' \ |
| 265 | f'instead of {len(proj_mat.shape)}.' |
| 266 | d1, d2 = proj_mat.shape[:2] |
| 267 | assert (d1 == 3 and d2 == 3) or (d1 == 3 and d2 == 4) or \ |
| 268 | (d1 == 4 and d2 == 4), 'The shape of the projection matrix ' \ |
| 269 | f'({d1}*{d2}) is not supported.' |
| 270 | if d1 == 3: |
| 271 | proj_mat_expanded = torch.eye(4, |
| 272 | device=proj_mat.device, |
| 273 | dtype=proj_mat.dtype) |
| 274 | proj_mat_expanded[:d1, :d2] = proj_mat |
| 275 | proj_mat = proj_mat_expanded |
| 276 | |
| 277 | # previous implementation use new_zeros, new_one yields better results |
| 278 | points_4 = torch.cat([points_3d, points_3d.new_ones(points_shape)], dim=-1) |
| 279 | |
| 280 | point_2d = points_4 @ proj_mat.T |
| 281 | point_2d_res = point_2d[..., :2] / point_2d[..., 2:3] |
| 282 | |
| 283 | if with_depth: |
| 284 | point_2d_res = torch.cat([point_2d_res, point_2d[..., 2:3]], dim=-1) |
| 285 | |
| 286 | return point_2d_res |
| 287 | |
| 288 | |
| 289 | @array_converter(apply_to=('points_3d', 'proj_mat')) |
no test coverage detected