Convert the inverse relative transformations from ModelOutput to extrinsics. Each inverse relative transformation transforms points from frame {i + 1}'s camera space to frame i's camera space. Since our extrinsics are in camera-to-world format, this means that expressed in terms of camer
(
inverse_relative_transformations: Float[Tensor, "*batch pair 4 4"],
)
| 185 | |
| 186 | |
| 187 | def get_extrinsics( |
| 188 | inverse_relative_transformations: Float[Tensor, "*batch pair 4 4"], |
| 189 | ) -> Float[Tensor, "*batch pair+1 4 4"]: |
| 190 | """Convert the inverse relative transformations from ModelOutput to extrinsics. |
| 191 | Each inverse relative transformation transforms points from frame {i + 1}'s |
| 192 | camera space to frame i's camera space. Since our extrinsics are in |
| 193 | camera-to-world format, this means that expressed in terms of camera poses, each |
| 194 | inverse relative transformation is (P_i^-1 @ P_{i + 1}). If we assume that P_0 |
| 195 | is I (the identity pose), we can thus extract camera poses as follows: |
| 196 | |
| 197 | P_n = (I @ P_1) @ (P_1^-1 @ P_2) @ ... @ (P_{n - 1}^-1 @ P_n) |
| 198 | |
| 199 | This is slightly counterintuitive, since transformations are generally composed |
| 200 | by right-to-left multiplication. |
| 201 | """ |
| 202 | *batch, step, _, _ = inverse_relative_transformations.shape |
| 203 | device = inverse_relative_transformations.device |
| 204 | pose = torch.eye(4, dtype=torch.float32, device=device) |
| 205 | pose = pose.expand((*batch, 4, 4)).contiguous() |
| 206 | result = [pose] |
| 207 | for i in range(step): |
| 208 | pose = pose @ inverse_relative_transformations[..., i, :, :] |
| 209 | result.append(pose) |
| 210 | return torch.stack(result, dim=-3) |
| 211 | |
| 212 | |
| 213 | def align_surfaces( |
no outgoing calls
no test coverage detected