(
path: Path,
extrinsics: Float[Tensor, "frame 4 4"],
intrinsics: Float[Tensor, "frame 3 3"],
image_names: list[str],
image_shape: tuple[int, int],
)
| 172 | |
| 173 | |
| 174 | def write_colmap_model( |
| 175 | path: Path, |
| 176 | extrinsics: Float[Tensor, "frame 4 4"], |
| 177 | intrinsics: Float[Tensor, "frame 3 3"], |
| 178 | image_names: list[str], |
| 179 | image_shape: tuple[int, int], |
| 180 | ) -> None: |
| 181 | h, w = image_shape |
| 182 | |
| 183 | # Define the cameras (intrinsics). |
| 184 | cameras = {} |
| 185 | for index, k in enumerate(intrinsics): |
| 186 | id = index + 1 |
| 187 | |
| 188 | # Undo the normalization we apply to the intrinsics. |
| 189 | k = k.detach().clone() |
| 190 | k[0] *= w |
| 191 | k[1] *= h |
| 192 | |
| 193 | # Extract the intrinsics' parameters. |
| 194 | fx = k[0, 0] |
| 195 | fy = k[1, 1] |
| 196 | cx = k[0, 2] |
| 197 | cy = k[1, 2] |
| 198 | |
| 199 | cameras[id] = Camera(id, "PINHOLE", w, h, (fx, fy, cx, cy)) |
| 200 | |
| 201 | # Define the images (extrinsics and names). |
| 202 | images = {} |
| 203 | for index, (c2w, name) in enumerate(zip(extrinsics, image_names)): |
| 204 | id = index + 1 |
| 205 | |
| 206 | # Convert the extrinsics to COLMAP's format. |
| 207 | w2c = c2w.inverse().detach().cpu().numpy() |
| 208 | qx, qy, qz, qw = R.from_matrix(w2c[:3, :3]).as_quat() |
| 209 | qvec = np.array((qw, qx, qy, qz)) |
| 210 | tvec = w2c[:3, 3] |
| 211 | images[id] = Image(id, qvec, tvec, id, name, [], []) |
| 212 | |
| 213 | path.mkdir(exist_ok=True, parents=True) |
| 214 | write_model(cameras, images, None, path) |
no outgoing calls
no test coverage detected