| | |
| |
|
| | import numpy as np |
| | import torch |
| |
|
| |
|
| | def from_homogeneous(points, eps: float = 1e-8): |
| | """Remove the homogeneous dimension of N-dimensional points. |
| | Args: |
| | points: torch.Tensor or numpy.ndarray with size (..., N+1). |
| | Returns: |
| | A torch.Tensor or numpy ndarray with size (..., N). |
| | """ |
| | return points[..., :-1] / (points[..., -1:] + eps) |
| |
|
| |
|
| | def to_homogeneous(points): |
| | """Convert N-dimensional points to homogeneous coordinates. |
| | Args: |
| | points: torch.Tensor or numpy.ndarray with size (..., N). |
| | Returns: |
| | A torch.Tensor or numpy.ndarray with size (..., N+1). |
| | """ |
| | if isinstance(points, torch.Tensor): |
| | pad = points.new_ones(points.shape[:-1] + (1,)) |
| | return torch.cat([points, pad], dim=-1) |
| | elif isinstance(points, np.ndarray): |
| | pad = np.ones((points.shape[:-1] + (1,)), dtype=points.dtype) |
| | return np.concatenate([points, pad], axis=-1) |
| | else: |
| | raise ValueError |
| |
|
| |
|
| | @torch.jit.script |
| | def undistort_points(pts, dist): |
| | dist = dist.unsqueeze(-2) |
| | ndist = dist.shape[-1] |
| | undist = pts |
| | valid = torch.ones(pts.shape[:-1], device=pts.device, dtype=torch.bool) |
| | if ndist > 0: |
| | k1, k2 = dist[..., :2].split(1, -1) |
| | r2 = torch.sum(pts**2, -1, keepdim=True) |
| | radial = k1 * r2 + k2 * r2**2 |
| | undist = undist + pts * radial |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | limited = ((k2 > 0) & ((9 * k1**2 - 20 * k2) > 0)) | ((k2 <= 0) & (k1 > 0)) |
| | limit = torch.abs( |
| | torch.where( |
| | k2 > 0, |
| | (torch.sqrt(9 * k1**2 - 20 * k2) - 3 * k1) / (10 * k2), |
| | 1 / (3 * k1), |
| | ) |
| | ) |
| | valid = valid & torch.squeeze(~limited | (r2 < limit), -1) |
| |
|
| | if ndist > 2: |
| | p12 = dist[..., 2:] |
| | p21 = p12.flip(-1) |
| | uv = torch.prod(pts, -1, keepdim=True) |
| | undist = undist + 2 * p12 * uv + p21 * (r2 + 2 * pts**2) |
| |
|
| | return undist, valid |
| |
|