Generate a camera path that looks at the world origin Args: num_poses: number of camera poses sampled on the circle d_to_origin: distance to the origin r_circle: radius of the circle center_direction: (2,) theta
(
num_poses: int,
d_to_origin: float,
r_circle: float,
center_angles: T.Union[torch.Tensor, np.ndarray, T.List[float]],
invert_yz: bool = True,
alt_yaxis: bool = False,
)
| 2031 | |
| 2032 | |
| 2033 | def generate_camera_circle_path( |
| 2034 | num_poses: int, |
| 2035 | d_to_origin: float, |
| 2036 | r_circle: float, |
| 2037 | center_angles: T.Union[torch.Tensor, np.ndarray, T.List[float]], |
| 2038 | invert_yz: bool = True, |
| 2039 | alt_yaxis: bool = False, |
| 2040 | ) -> T.Union[torch.Tensor, np.ndarray]: |
| 2041 | """ |
| 2042 | Generate a camera path that looks at the world origin |
| 2043 | Args: |
| 2044 | num_poses: |
| 2045 | number of camera poses sampled on the circle |
| 2046 | d_to_origin: |
| 2047 | distance to the origin |
| 2048 | r_circle: |
| 2049 | radius of the circle |
| 2050 | center_direction: |
| 2051 | (2,) theta (angle between x-axis), phi (angle between xy plane), |
| 2052 | the viewing direction of the center of the circle. All in degree. |
| 2053 | The angles are given in the final coordinate (after yz is inverted) |
| 2054 | invert_yz: |
| 2055 | whether to invert the direction of y axis and z axis (since images y coord is flipped) |
| 2056 | This is to account for the difference in the image coordinate (x to right, y to down, z to far) |
| 2057 | and the world/opengl coordinate (x to right, y to up, z to us) |
| 2058 | alt_yaxis: |
| 2059 | an option to use an alternative definition of yaxis and makes a more stable circular path |
| 2060 | Returns: |
| 2061 | (num_poses, 4, 4) camera poses (that converts camera coord to world coords) |
| 2062 | """ |
| 2063 | |
| 2064 | if isinstance(center_angles, np.ndarray): |
| 2065 | center_angles = torch.from_numpy(center_angles).float() |
| 2066 | elif isinstance(center_angles, (list, tuple)): |
| 2067 | center_angles = torch.tensor(center_angles).float() |
| 2068 | |
| 2069 | center_angles = center_angles.float() |
| 2070 | |
| 2071 | if invert_yz: |
| 2072 | # the coordinate is currently pre-yz-inverted |
| 2073 | # but center_angles are given after yz-inverted |
| 2074 | center_angles = -1 * center_angles |
| 2075 | |
| 2076 | # generate a circle on the xy plane (i.e., on the plane z = d_to_origin) |
| 2077 | thetas = torch.linspace(0, torch.pi * 2, num_poses) + torch.pi # (n,) |
| 2078 | cam_positions_c = torch.stack( |
| 2079 | [ |
| 2080 | torch.cos(thetas) * float(r_circle), |
| 2081 | torch.sin(thetas) * float(r_circle), |
| 2082 | torch.ones(num_poses) * float(d_to_origin), |
| 2083 | ], dim=1) # (n, 3) |
| 2084 | |
| 2085 | # print(f'cam_positions_c.shape = {cam_positions_c.shape}') |
| 2086 | |
| 2087 | # rotate the camera positions |
| 2088 | v1 = torch.tensor([0, 0, 1], dtype=torch.float) |
| 2089 | v2 = torch.stack( |
| 2090 | [ |
nothing calls this directly
no outgoing calls
no test coverage detected