gradslam.geometry¶
gradslam.geometry.projutils¶
- homogenize_points(pts: torch.Tensor)[source]¶
Convert a set of points to homogeneous coordinates.
- Parameters
pts (torch.Tensor) – Tensor containing points to be homogenized.
- Returns
Homogeneous coordinates of pts.
- Return type
- Shape:
pts: \((N, *, K)\) where \(N\) indicates the number of points in a cloud if the shape is \((N, K)\) and indicates batchsize if the number of dimensions is greater than 2. Also, \(*\) means any number of additional dimensions, and K is the dimensionality of each point.
Output: \((N, *, K + 1)\) where all but the last dimension are the same shape as pts.
Examples:
>>> pts = torch.rand(10, 3) >>> pts_homo = homogenize_points(pts) >>> pts_homo.shape torch.Size([10, 4])
- unhomogenize_points(pts: torch.Tensor, eps: float = 1e-06) → torch.Tensor[source]¶
Convert a set of points from homogeneous coordinates to Euclidean coordinates. This is usually done by taking each point \((X, Y, Z, W)\) and dividing it by the last coordinate \((w)\).
- Parameters
pts (torch.Tensor) – Tensor containing points to be unhomogenized.
- Returns
‘Unhomogenized’ points
- Return type
- Shape:
pts: \((N, *, K)\) where \(N\) indicates the number of points in a cloud if the shape is \((N, K)\) and indicates batchsize if the number of dimensions is greater than 2. Also, \(*\) means any number of additional dimensions, and K is the dimensionality of each point.
output: \((N, *, K-1)\) where all but the last dimension are the same shape as pts.
Examples:
>>> pts = torch.rand(10, 3) >>> pts_unhomo = unhomogenize_points(pts) >>> pts_unhomo.shape torch.Size([10, 2])
- project_points(cam_coords: torch.Tensor, proj_mat: torch.Tensor, eps: Optional[float] = 1e-06) → torch.Tensor[source]¶
Projects points from the camera coordinate frame to the image (pixel) frame.
- Parameters
cam_coords (torch.Tensor) – pixel coordinates (defined in the frame of the first camera).
proj_mat (torch.Tensor) – projection matrix between the reference and the non-reference camera frame.
- Returns
Image (pixel) coordinates corresponding to the input 3D points.
- Return type
- Shapes:
cam_coords: \((N, *, 3)\) or \((*, 4)\) where \(*\) indicates an arbitrary number of dimensions. Here \(N\) indicates the number of points in a cloud if the shape is \((N, 3)\) and indicates batchsize if the number of dimensions is greater than 2.
proj_mat: \((*, 4, 4)\) where \(*\) indicates an arbitrary number of dimensions. dimension contains a \((4, 4)\) camera projection matrix.
Output: \((N, *, 2)\), where \(*\) indicates the same dimensions as in cam_coords. Here \(N\) indicates the number of points in a cloud if the shape is \((N, 3)\) and indicates batchsize if the number of dimensions is greater than 2.
Examples:
>>> # Case 1: Input cam_coords are homogeneous, no batchsize dimension. >>> cam_coords = torch.rand(10, 4) >>> proj_mat = torch.rand(4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([10, 2]) >>> # Case 2: Input cam_coords are homogeneous and batched. Broadcast proj_mat across batch. >>> cam_coords = torch.rand(2, 10, 4) >>> proj_mat = torch.rand(4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([2, 10, 2]) >>> # Case 3: Input cam_coords are homogeneous and batched. A different proj_mat applied to each element. >>> cam_coords = torch.rand(2, 10, 4) >>> proj_mat = torch.rand(2, 4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([2, 10, 2]) >>> # Case 4: Similar to case 1, but cam_coords are unhomogeneous. >>> cam_coords = torch.rand(10, 3) >>> proj_mat = torch.rand(4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([10, 2]) >>> # Case 5: Similar to case 2, but cam_coords are unhomogeneous. >>> cam_coords = torch.rand(2, 10, 3) >>> proj_mat = torch.rand(4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([2, 10, 2]) >>> # Case 6: Similar to case 3, but cam_coords are unhomogeneous. >>> cam_coords = torch.rand(2, 10, 3) >>> proj_mat = torch.rand(2, 4, 4) >>> pixel_coords = project_points(cam_coords, proj_mat) >>> pixel_coords.shape torch.Size([2, 10, 2])
- unproject_points(pixel_coords: torch.Tensor, intrinsics_inv: torch.Tensor, depths: torch.Tensor) → torch.Tensor[source]¶
Unprojects points from the image (pixel) frame to the camera coordinate frame.
- Parameters
pixel_coords (torch.Tensor) – pixel coordinates.
intrinsics_inv (torch.Tensor) – inverse of the camera intrinsics matrix.
depths (torch.Tensor) – per-pixel depth estimates.
- Returns
camera coordinates
- Return type
- Shapes:
pixel_coords: \((N, *, 2)\) or \((*, 3)\), where * indicates an arbitrary number of dimensions. Here \(N\) indicates the number of points in a cloud if the shape is \((N, 3)\) and indicates batchsize if the number of dimensions is greater than 2.
intrinsics_inv: \((*, 3, 3)\), where * indicates an arbitrary number of dimensions.
depths: \((N, *)\) where * indicates the same number of dimensions as in pixel_coords. Here \(N\) indicates the number of points in a cloud if the shape is \((N, 3)\) and indicates batchsize if the number of dimensions is greater than 2.
output: \((N, *, 3)\) where * indicates the same number of dimensions as in pixel_coords. Here \(N\) indicates the number of points in a cloud if the shape is \((N, 3)\) and indicates batchsize if the number of dimensions is greater than 2.
Examples:
>>> # Case 1: Input pixel_coords are homogeneous, no batchsize dimension. >>> pixel_coords = torch.rand(10, 3) >>> intrinsics_inv = torch.rand(3, 3) >>> depths = torch.rand(10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([10, 3]) >>> # Case 2: Input pixel_coords are homogeneous, with a batchsize dimension. But, intrinsics_inv is not. >>> pixel_coords = torch.rand(2, 10, 3) >>> intrinsics_inv = torch.rand(3, 3) >>> depths = torch.rand(2, 10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([2, 10, 3]) >>> # Case 3: Input pixel_coords are homogeneous, with a batchsize dimension. intrinsics_inv is batched. >>> pixel_coords = torch.rand(2, 10, 3) >>> intrinsics_inv = torch.rand(2, 3, 3) >>> depths = torch.rand(2, 10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([2, 10, 3]) >>> # Case 4: Similar to case 1, but input pixel_coords are unhomogeneous. >>> pixel_coords = torch.rand(10, 2) >>> intrinsics_inv = torch.rand(3, 3) >>> depths = torch.rand(10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([10, 3]) >>> # Case 5: Similar to case 2, but input pixel_coords are unhomogeneous. >>> pixel_coords = torch.rand(2, 10, 2) >>> intrinsics_inv = torch.rand(3, 3) >>> depths = torch.rand(2, 10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([2, 10, 3]) >>> # Case 6: Similar to case 3, but input pixel_coords are unhomogeneous. >>> pixel_coords = torch.rand(2, 10, 2) >>> intrinsics_inv = torch.rand(2, 3, 3) >>> depths = torch.rand(2, 10) >>> cam_coords = unproject_points(pixel_coords, intrinsics_inv, depths) >>> cam_coords.shape torch.Size([2, 10, 3])
- inverse_intrinsics(K: torch.Tensor, eps: float = 1e-06) → torch.Tensor[source]¶
Efficient inversion of intrinsics matrix
- Parameters
K (torch.Tensor) – Intrinsics matrix
eps (float) – Epsilon for numerical stability
- Returns
Inverse of intrinsics matrices
- Return type
- Shape:
K: \((*, 4, 4)\) or \((*, 3, 3)\)
Kinv: Matches shape of K (\((*, 4, 4)\) or \((*, 3, 3)\))