| |
|
|
| 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 |
|
|