fastdev.xform.transforms ======================== .. py:module:: fastdev.xform.transforms Module Contents --------------- .. py:function:: transform_points(pts: jaxtyping.Float[torch.Tensor, ... n 3], tf_mat: jaxtyping.Float[torch.Tensor, ... 4 4]) -> jaxtyping.Float[torch.Tensor, ... n 3] Apply a transformation matrix on a set of 3D points. :param pts: 3D points, could be [... n 3] :type pts: torch.Tensor :param tf_mat: Transformation matrix, could be [... 4 4] :type tf_mat: torch.Tensor :returns: Transformed pts in shape of [... n 3] .. rubric:: Examples >>> pts = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]) >>> tf_mat = torch.tensor([[0.0, 1.0, 0.0, 1.0], [0.0, 0.0, 1.0, 2.0], [1.0, 0.0, 0.0, 3.0], [0.0, 0.0, 0.0, 1.0]]) >>> transform_points(pts, tf_mat) tensor([[3., 5., 4.], [6., 8., 7.]]) .. note:: The dimension number of `pts` and `tf_mat` should be the same. The batch dimensions (...) are broadcasted_ (and thus must be broadcastable). We don't adopt the shapes [... 3] and [... 4 4] because there is no real broadcasted vector-matrix multiplication in pytorch. [... 3] and [... 4 4] will be converted to [... 1 3] and [... 4 4] and apply a broadcasted matrix-matrix multiplication. .. _broadcasted: https://pytorch.org/docs/stable/notes/broadcasting.html .. py:function:: rotate_points(pts: jaxtyping.Float[torch.Tensor, ... n 3], rot_mat: jaxtyping.Float[torch.Tensor, ... 3 3]) -> jaxtyping.Float[torch.Tensor, ... n 3] Rotate a set of 3D points by a rotation matrix. :param pts: 3D points in shape [... n 3]. :type pts: torch.Tensor :param rot_mat: Rotation matrix in shape [... 3 3]. :type rot_mat: torch.Tensor :returns: Rotated points in shape [... n 3]. :rtype: torch.Tensor .. py:function:: project_points(pts: torch.Tensor, intr_mat: torch.Tensor, return_depth: Literal[False] = False) -> torch.Tensor project_points(pts: torch.Tensor, intr_mat: torch.Tensor, return_depth: Literal[True]) -> Tuple[torch.Tensor, torch.Tensor] Project 3D points in the camera space to the image plane. :param pts: 3D points, could be Nx3 or BxNx3. :param intr_mat: Intrinsic matrix, could be 3x3 or Bx3x3. :returns: the order is uv other than xy. depth (if return_depth): depth in the camera space. :rtype: pixels .. py:function:: unproject_points(pixels, depth, intr_mat) Unproject pixels in the image plane to 3D points in the camera space. :param pixels: Pixels in the image plane, could be Nx2 or BxNx2. The order is uv rather than xy. :param depth: Depth in the camera space, could be N, Nx1, BxN or BxNx1. :param intr_mat: Intrinsic matrix, could be 3x3 or Bx3x3. :returns: 3D points, Nx3 or BxNx3. :rtype: pts .. py:function:: inverse_tf_mat(rot_or_tf_mat: torch.Tensor) -> torch.Tensor Inverse a rotation matrix or a transformation matrix. Reference_ :param rot_or_tf_mat: Rotation matrix (in shape [..., 3, 3]) or transformation matrix (in shape [..., 4, 4]). :type rot_or_tf_mat: torch.Tensor :returns: Inversed matrix. :rtype: torch.Tensor .. rubric:: Examples >>> tf_mat = torch.tensor([[0, 1, 0, 1], [0, 0, 1, 2], [1, 0, 0, 3], [0, 0, 0, 1]], dtype=torch.float32) >>> torch.allclose(inverse_tf_mat(tf_mat) @ tf_mat, torch.eye(4)) True >>> rot_mat = torch.tensor([[0, 1, 0], [0, 0, 1], [1, 0, 0]], dtype=torch.float32) >>> torch.allclose(inverse_tf_mat(rot_mat) @ rot_mat, torch.eye(3)) True .. _Reference: https://math.stackexchange.com/a/1315407/757569 .. py:function:: swap_major(rot_or_tf_mat: torch.Tensor) -> torch.Tensor Swap the major of a rotation matrix or a transformation matrix. Reference_ :param rot_or_tf_mat: Rotation or transformation matrix in shape [..., 3, 3] or [..., 4, 4]. :type rot_or_tf_mat: torch.Tensor :returns: Matrix with swapped major. :rtype: torch.Tensor .. _Reference: https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/row-major-vs-column-major-vector # noqa .. py:function:: to_homo(pts_3d: jaxtyping.Float[torch.Tensor, ... 3]) -> jaxtyping.Float[torch.Tensor, ... 4] Convert Cartesian 3D points to Homogeneous 4D points. :param pts_3d: Cartesian 3D points in shape [... 3]. :type pts_3d: torch.Tensor :returns: Homogeneous 4D points in shape [... 4]. :rtype: torch.Tensor .. rubric:: Examples >>> pts = torch.tensor([[0, 1, 0], [0, 0, 1], [1, 0, 0]], dtype=torch.float32) >>> to_homo(pts) tensor([[0., 1., 0., 1.], [0., 0., 1., 1.], [1., 0., 0., 1.]]) .. py:function:: rot_tl_to_tf_mat(rot_mat: Optional[jaxtyping.Float[torch.Tensor, ... 3 3]] = None, tl: Optional[jaxtyping.Float[torch.Tensor, ... 3]] = None) -> jaxtyping.Float[torch.Tensor, ... 4 4] Build transformation matrix with rotation matrix and translation vector. :param rot_mat: Rotation matrix in shape [... 3 3]. Defaults to None. :type rot_mat: torch.Tensor, optional :param tl: Translation vector in shape [... 3]. Defaults to None. :type tl: torch.Tensor, optional :returns: Transformation matrix in shape [... 4 4]. :rtype: torch.Tensor .. rubric:: Examples >>> rot_mat = torch.tensor([[0, 1, 0], [0, 0, 1], [1, 0, 0]], dtype=torch.float32) >>> tl = torch.tensor([1, 2, 3], dtype=torch.float32) >>> rot_tl_to_tf_mat(rot_mat, tl) tensor([[0., 1., 0., 1.], [0., 0., 1., 2.], [1., 0., 0., 3.], [0., 0., 0., 1.]]) >>> rot_tl_to_tf_mat(tl=tl) tensor([[1., 0., 0., 1.], [0., 1., 0., 2.], [0., 0., 1., 3.], [0., 0., 0., 1.]]) >>> rot_tl_to_tf_mat(rot_mat=rot_mat) tensor([[0., 1., 0., 0.], [0., 0., 1., 0.], [1., 0., 0., 0.], [0., 0., 0., 1.]]) .. py:function:: expand_tf_mat(tf_mat: jaxtyping.Float[torch.Tensor, ... 3 4]) -> jaxtyping.Float[torch.Tensor, ... 4 4] Expand transformation matrix of shape [... 3 4] to shape [... 4 4]. :param tf_mat: Transformation matrix in shape [... 3 4] or [... 4 4]. :type tf_mat: torch.Tensor :returns: Expanded transformation matrix in shape [... 4 4]. :rtype: torch.Tensor .. rubric:: Examples >>> tf_mat = torch.tensor([[0, 1, 0, 1], [0, 0, 1, 2], [1, 0, 0, 3]], dtype=torch.float32) >>> expand_tf_mat(tf_mat) tensor([[0., 1., 0., 1.], [0., 0., 1., 2.], [1., 0., 0., 3.], [0., 0., 0., 1.]])