mirror of
https://github.com/facebookresearch/pytorch3d.git
synced 2025-08-03 04:12:48 +08:00
Summary: This fixes a recently introduced circular import: the problem went unnoticed by having `pytorch3d.renderer` imported first... Reviewed By: bottler Differential Revision: D29686235 fbshipit-source-id: 4b9f2faecec2cc8347ee259cfc359dc9e4f67784
160 lines
6.1 KiB
Python
160 lines
6.1 KiB
Python
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
# All rights reserved.
|
|
#
|
|
# This source code is licensed under the BSD-style license found in the
|
|
# LICENSE file in the root directory of this source tree.
|
|
|
|
from typing import Tuple
|
|
|
|
import torch
|
|
|
|
from ..renderer import PerspectiveCameras
|
|
from ..renderer.camera_conversions import (
|
|
_cameras_from_opencv_projection,
|
|
_opencv_from_cameras_projection,
|
|
_pulsar_from_cameras_projection,
|
|
_pulsar_from_opencv_projection,
|
|
)
|
|
|
|
|
|
def cameras_from_opencv_projection(
|
|
R: torch.Tensor,
|
|
tvec: torch.Tensor,
|
|
camera_matrix: torch.Tensor,
|
|
image_size: torch.Tensor,
|
|
) -> PerspectiveCameras:
|
|
"""
|
|
Converts a batch of OpenCV-conventioned cameras parametrized with the
|
|
rotation matrices `R`, translation vectors `tvec`, and the camera
|
|
calibration matrices `camera_matrix` to `PerspectiveCameras` in PyTorch3D
|
|
convention.
|
|
|
|
More specifically, the conversion is carried out such that a projection
|
|
of a 3D shape to the OpenCV-conventioned screen of size `image_size` results
|
|
in the same image as a projection with the corresponding PyTorch3D camera
|
|
to the NDC screen convention of PyTorch3D.
|
|
|
|
More specifically, the OpenCV convention projects points to the OpenCV screen
|
|
space as follows:
|
|
```
|
|
x_screen_opencv = camera_matrix @ (R @ x_world + tvec)
|
|
```
|
|
followed by the homogenization of `x_screen_opencv`.
|
|
|
|
Note:
|
|
The parameters `R, tvec, camera_matrix` correspond to the outputs of
|
|
`cv2.decomposeProjectionMatrix`.
|
|
|
|
The `rvec` parameter of the `cv2.projectPoints` is an axis-angle vector
|
|
that can be converted to the rotation matrix `R` expected here by
|
|
calling the `so3_exp_map` function.
|
|
|
|
Args:
|
|
R: A batch of rotation matrices of shape `(N, 3, 3)`.
|
|
tvec: A batch of translation vectors of shape `(N, 3)`.
|
|
camera_matrix: A batch of camera calibration matrices of shape `(N, 3, 3)`.
|
|
image_size: A tensor of shape `(N, 2)` containing the sizes of the images
|
|
(height, width) attached to each camera.
|
|
|
|
Returns:
|
|
cameras_pytorch3d: A batch of `N` cameras in the PyTorch3D convention.
|
|
"""
|
|
return _cameras_from_opencv_projection(R, tvec, camera_matrix, image_size)
|
|
|
|
|
|
def opencv_from_cameras_projection(
|
|
cameras: PerspectiveCameras,
|
|
image_size: torch.Tensor,
|
|
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
|
|
"""
|
|
Converts a batch of `PerspectiveCameras` into OpenCV-convention
|
|
rotation matrices `R`, translation vectors `tvec`, and the camera
|
|
calibration matrices `camera_matrix`. This operation is exactly the inverse
|
|
of `cameras_from_opencv_projection`.
|
|
|
|
Note:
|
|
The outputs `R, tvec, camera_matrix` correspond to the outputs of
|
|
`cv2.decomposeProjectionMatrix`.
|
|
|
|
The `rvec` parameter of the `cv2.projectPoints` is an axis-angle vector
|
|
that can be converted from the returned rotation matrix `R` here by
|
|
calling the `so3_log_map` function.
|
|
|
|
Args:
|
|
cameras: A batch of `N` cameras in the PyTorch3D convention.
|
|
image_size: A tensor of shape `(N, 2)` containing the sizes of the images
|
|
(height, width) attached to each camera.
|
|
return_as_rotmat (bool): If set to True, return the full 3x3 rotation
|
|
matrices. Otherwise, return an axis-angle vector (default).
|
|
|
|
Returns:
|
|
R: A batch of rotation matrices of shape `(N, 3, 3)`.
|
|
tvec: A batch of translation vectors of shape `(N, 3)`.
|
|
camera_matrix: A batch of camera calibration matrices of shape `(N, 3, 3)`.
|
|
"""
|
|
return _opencv_from_cameras_projection(cameras, image_size)
|
|
|
|
|
|
def pulsar_from_opencv_projection(
|
|
R: torch.Tensor,
|
|
tvec: torch.Tensor,
|
|
camera_matrix: torch.Tensor,
|
|
image_size: torch.Tensor,
|
|
znear: float = 0.1,
|
|
) -> torch.Tensor:
|
|
"""
|
|
Convert OpenCV style camera parameters to Pulsar style camera parameters.
|
|
|
|
Note:
|
|
* Pulsar does NOT support different focal lengths for x and y.
|
|
For conversion, we use the average of fx and fy.
|
|
* The Pulsar renderer MUST use a left-handed coordinate system for this
|
|
mapping to work.
|
|
* The resulting image will be vertically flipped - which has to be
|
|
addressed AFTER rendering by the user.
|
|
* The parameters `R, tvec, camera_matrix` correspond to the outputs
|
|
of `cv2.decomposeProjectionMatrix`.
|
|
|
|
Args:
|
|
R: A batch of rotation matrices of shape `(N, 3, 3)`.
|
|
tvec: A batch of translation vectors of shape `(N, 3)`.
|
|
camera_matrix: A batch of camera calibration matrices of shape `(N, 3, 3)`.
|
|
image_size: A tensor of shape `(N, 2)` containing the sizes of the images
|
|
(height, width) attached to each camera.
|
|
znear (float): The near clipping value to use for Pulsar.
|
|
|
|
Returns:
|
|
cameras_pulsar: A batch of `N` Pulsar camera vectors in the Pulsar
|
|
convention `(N, 13)` (3 translation, 6 rotation, focal_length, sensor_width,
|
|
c_x, c_y).
|
|
"""
|
|
return _pulsar_from_opencv_projection(R, tvec, camera_matrix, image_size, znear)
|
|
|
|
|
|
def pulsar_from_cameras_projection(
|
|
cameras: PerspectiveCameras,
|
|
image_size: torch.Tensor,
|
|
) -> torch.Tensor:
|
|
"""
|
|
Convert PyTorch3D `PerspectiveCameras` to Pulsar style camera parameters.
|
|
|
|
Note:
|
|
* Pulsar does NOT support different focal lengths for x and y.
|
|
For conversion, we use the average of fx and fy.
|
|
* The Pulsar renderer MUST use a left-handed coordinate system for this
|
|
mapping to work.
|
|
* The resulting image will be vertically flipped - which has to be
|
|
addressed AFTER rendering by the user.
|
|
|
|
Args:
|
|
cameras: A batch of `N` cameras in the PyTorch3D convention.
|
|
image_size: A tensor of shape `(N, 2)` containing the sizes of the images
|
|
(height, width) attached to each camera.
|
|
|
|
Returns:
|
|
cameras_pulsar: A batch of `N` Pulsar camera vectors in the Pulsar
|
|
convention `(N, 13)` (3 translation, 6 rotation, focal_length, sensor_width,
|
|
c_x, c_y).
|
|
"""
|
|
return _pulsar_from_cameras_projection(cameras, image_size)
|