mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-11 10:34:29 +08:00
Add PyTorch jit-ing to the undistort computation for speed (#776)
This commit is contained in:
parent
a48a81fc48
commit
7ebe1f88bb
@ -271,60 +271,14 @@ def get_distortion_params(
|
||||
return torch.Tensor([k1, k2, k3, k4, p1, p2])
|
||||
|
||||
|
||||
def radial_and_tangential_undistort(
|
||||
coords: TensorType["num_coords":..., 2],
|
||||
distortion_params: TensorType["num_coords":..., 6],
|
||||
eps: float = 1e-9,
|
||||
max_iterations=10,
|
||||
) -> TensorType["num_coords":..., 2]:
|
||||
"""Computes undistorted coords given opencv distortion parameters.
|
||||
Addapted from MultiNeRF
|
||||
https://github.com/google-research/multinerf/blob/b02228160d3179300c7d499dca28cb9ca3677f32/internal/camera_utils.py#L477-L509
|
||||
|
||||
Args:
|
||||
coords: The distorted coordinates.
|
||||
distortion_params: The distortion parameters [k1, k2, k3, k4, p1, p2].
|
||||
eps: The epsilon for the convergence.
|
||||
max_iterations: The maximum number of iterations to perform.
|
||||
|
||||
Returns:
|
||||
The undistorted coordinates.
|
||||
"""
|
||||
|
||||
# Initialize from the distorted point.
|
||||
x = torch.clone(coords[..., 0])
|
||||
y = torch.clone(coords[..., 1])
|
||||
|
||||
for _ in range(max_iterations):
|
||||
fx, fy, fx_x, fx_y, fy_x, fy_y = _compute_residual_and_jacobian(
|
||||
x=x, y=y, xd=coords[..., 0], yd=coords[..., 1], distortion_params=distortion_params
|
||||
)
|
||||
denominator = fy_x * fx_y - fx_x * fy_y
|
||||
x_numerator = fx * fy_y - fy * fx_y
|
||||
y_numerator = fy * fx_x - fx * fy_x
|
||||
step_x = torch.where(torch.abs(denominator) > eps, x_numerator / denominator, torch.zeros_like(denominator))
|
||||
step_y = torch.where(torch.abs(denominator) > eps, y_numerator / denominator, torch.zeros_like(denominator))
|
||||
|
||||
x = x + step_x
|
||||
y = y + step_y
|
||||
|
||||
return torch.stack([x, y], dim=-1)
|
||||
|
||||
|
||||
@torch.jit.script
|
||||
def _compute_residual_and_jacobian(
|
||||
x: TensorType["num_coords":...],
|
||||
y: TensorType["num_coords":...],
|
||||
xd: TensorType["num_coords":...],
|
||||
yd: TensorType["num_coords":...],
|
||||
distortion_params: TensorType["num_coords":..., 6],
|
||||
) -> Tuple[
|
||||
TensorType["num_coords":...],
|
||||
TensorType["num_coords":...],
|
||||
TensorType["num_coords":...],
|
||||
TensorType["num_coords":...],
|
||||
TensorType["num_coords":...],
|
||||
TensorType["num_coords":...],
|
||||
]:
|
||||
x: torch.Tensor,
|
||||
y: torch.Tensor,
|
||||
xd: torch.Tensor,
|
||||
yd: torch.Tensor,
|
||||
distortion_params: torch.Tensor,
|
||||
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor,]:
|
||||
"""Auxiliary function of radial_and_tangential_undistort() that computes residuals and jacobians.
|
||||
Adapted from MultiNeRF:
|
||||
https://github.com/google-research/multinerf/blob/b02228160d3179300c7d499dca28cb9ca3677f32/internal/camera_utils.py#L427-L474
|
||||
@ -383,6 +337,47 @@ def _compute_residual_and_jacobian(
|
||||
return fx, fy, fx_x, fx_y, fy_x, fy_y
|
||||
|
||||
|
||||
@torch.jit.script
|
||||
def radial_and_tangential_undistort(
|
||||
coords: torch.Tensor,
|
||||
distortion_params: torch.Tensor,
|
||||
eps: float = 1e-9,
|
||||
max_iterations: int = 10,
|
||||
) -> torch.Tensor:
|
||||
"""Computes undistorted coords given opencv distortion parameters.
|
||||
Addapted from MultiNeRF
|
||||
https://github.com/google-research/multinerf/blob/b02228160d3179300c7d499dca28cb9ca3677f32/internal/camera_utils.py#L477-L509
|
||||
|
||||
Args:
|
||||
coords: The distorted coordinates.
|
||||
distortion_params: The distortion parameters [k1, k2, k3, k4, p1, p2].
|
||||
eps: The epsilon for the convergence.
|
||||
max_iterations: The maximum number of iterations to perform.
|
||||
|
||||
Returns:
|
||||
The undistorted coordinates.
|
||||
"""
|
||||
|
||||
# Initialize from the distorted point.
|
||||
x = coords[..., 0]
|
||||
y = coords[..., 1]
|
||||
|
||||
for _ in range(max_iterations):
|
||||
fx, fy, fx_x, fx_y, fy_x, fy_y = _compute_residual_and_jacobian(
|
||||
x=x, y=y, xd=coords[..., 0], yd=coords[..., 1], distortion_params=distortion_params
|
||||
)
|
||||
denominator = fy_x * fx_y - fx_x * fy_y
|
||||
x_numerator = fx * fy_y - fy * fx_y
|
||||
y_numerator = fy * fx_x - fx * fy_x
|
||||
step_x = torch.where(torch.abs(denominator) > eps, x_numerator / denominator, torch.zeros_like(denominator))
|
||||
step_y = torch.where(torch.abs(denominator) > eps, y_numerator / denominator, torch.zeros_like(denominator))
|
||||
|
||||
x = x + step_x
|
||||
y = y + step_y
|
||||
|
||||
return torch.stack([x, y], dim=-1)
|
||||
|
||||
|
||||
def rotation_matrix(a: TensorType[3], b: TensorType[3]) -> TensorType[3, 3]:
|
||||
"""Compute the rotation matrix that rotates vector a to vector b.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user