Generate a spiral camera path that looks at the world origin Args: num_poses: number of camera poses sampled on the spiral num_circle: number of circle the spiral made in xy plane init_phi: initial phi (angle between xy plane) of t
(
num_poses: int,
num_circle: int,
init_phi: float,
center_angles: T.Union[torch.Tensor, np.ndarray, T.List[float]],
r_max: float = 1,
r_min: float = 1,
r_freq: float = 1,
invert_yz: bool = True,
)
| 2290 | |
| 2291 | |
| 2292 | def generate_camera_spiral_path( |
| 2293 | num_poses: int, |
| 2294 | num_circle: int, |
| 2295 | init_phi: float, |
| 2296 | center_angles: T.Union[torch.Tensor, np.ndarray, T.List[float]], |
| 2297 | r_max: float = 1, |
| 2298 | r_min: float = 1, |
| 2299 | r_freq: float = 1, |
| 2300 | invert_yz: bool = True, |
| 2301 | ) -> T.Union[torch.Tensor, np.ndarray]: |
| 2302 | """ |
| 2303 | Generate a spiral camera path that looks at the world origin |
| 2304 | Args: |
| 2305 | num_poses: |
| 2306 | number of camera poses sampled on the spiral |
| 2307 | num_circle: |
| 2308 | number of circle the spiral made in xy plane |
| 2309 | init_phi: |
| 2310 | initial phi (angle between xy plane) of the path, the path will go from phi to -phi |
| 2311 | r_circle: |
| 2312 | radius of the spiral |
| 2313 | center_direction: |
| 2314 | (2,) theta (angle between x-axis), phi (angle between xy plane), |
| 2315 | the viewing direction of the center of the circle. All in degree. |
| 2316 | The angles are given in the final coordinate (after yz is inverted) |
| 2317 | invert_yz: |
| 2318 | whether to invert the direction of y axis and z axis (since images y coord is flipped) |
| 2319 | This is to account for the difference in the image coordinate (x to right, y to down, z to far) |
| 2320 | and the world/opengl coordinate (x to right, y to up, z to us) |
| 2321 | |
| 2322 | Returns: |
| 2323 | (num_poses, 4, 4) camera poses (that converts camera coord to world coords) |
| 2324 | """ |
| 2325 | |
| 2326 | if isinstance(center_angles, np.ndarray): |
| 2327 | center_angles = torch.from_numpy(center_angles).float() |
| 2328 | elif isinstance(center_angles, (list, tuple)): |
| 2329 | center_angles = torch.tensor(center_angles).float() |
| 2330 | |
| 2331 | center_angles = center_angles.float() |
| 2332 | |
| 2333 | if num_poses % 2 != 0: |
| 2334 | print('Warning: automatically change num_poses to be even') |
| 2335 | num_poses = num_poses + 1 |
| 2336 | |
| 2337 | if invert_yz: |
| 2338 | # the coordinate is currently pre-yz-inverted |
| 2339 | # but center_angles are given after yz-inverted |
| 2340 | center_angles = -1 * center_angles |
| 2341 | |
| 2342 | # generate a circle on the xy plane (i.e., on the plane z = d_to_origin) |
| 2343 | thetas = torch.linspace(0, torch.pi * 2 * num_circle, num_poses) + torch.pi # (n,) |
| 2344 | |
| 2345 | # uniformly sample along phi by cosine weighted sample |
| 2346 | # https://alexanderameye.github.io/notes/sampling-the-hemisphere/ |
| 2347 | |
| 2348 | # calculate complementary phi: angle between z axis and camara position |
| 2349 | init_z = torch.cos(torch.pi / 2 - torch.tensor(init_phi)) |
nothing calls this directly
no outgoing calls
no test coverage detected