Optimize a global scene, given a list of pairwise observations. Unlike PointCloudOptimizer, you can fix parts of the optimization process (partial poses/intrinsics) Graph node: images Graph edges: observations = (pred1, pred2)
| 15 | |
| 16 | |
| 17 | class ModularPointCloudOptimizer (BasePCOptimizer): |
| 18 | """ Optimize a global scene, given a list of pairwise observations. |
| 19 | Unlike PointCloudOptimizer, you can fix parts of the optimization process (partial poses/intrinsics) |
| 20 | Graph node: images |
| 21 | Graph edges: observations = (pred1, pred2) |
| 22 | """ |
| 23 | |
| 24 | def __init__(self, *args, optimize_pp=False, fx_and_fy=False, focal_brake=20, **kwargs): |
| 25 | super().__init__(*args, **kwargs) |
| 26 | self.has_im_poses = True # by definition of this class |
| 27 | self.focal_brake = focal_brake |
| 28 | |
| 29 | # adding thing to optimize |
| 30 | self.im_depthmaps = nn.ParameterList(torch.randn(H, W)/10-3 for H, W in self.imshapes) # log(depth) |
| 31 | self.im_poses = nn.ParameterList(self.rand_pose(self.POSE_DIM) for _ in range(self.n_imgs)) # camera poses |
| 32 | default_focals = [self.focal_brake * np.log(max(H, W)) for H, W in self.imshapes] |
| 33 | self.im_focals = nn.ParameterList(torch.FloatTensor([f, f] if fx_and_fy else [ |
| 34 | f]) for f in default_focals) # camera intrinsics |
| 35 | self.im_pp = nn.ParameterList(torch.zeros((2,)) for _ in range(self.n_imgs)) # camera intrinsics |
| 36 | self.im_pp.requires_grad_(optimize_pp) |
| 37 | |
| 38 | def preset_pose(self, known_poses, pose_msk=None): # cam-to-world |
| 39 | if isinstance(known_poses, torch.Tensor) and known_poses.ndim == 2: |
| 40 | known_poses = [known_poses] |
| 41 | for idx, pose in zip(self._get_msk_indices(pose_msk), known_poses): |
| 42 | if self.verbose: |
| 43 | print(f' (setting pose #{idx} = {pose[:3,3]})') |
| 44 | self._no_grad(self._set_pose(self.im_poses, idx, torch.tensor(pose), force=True)) |
| 45 | |
| 46 | # normalize scale if there's less than 1 known pose |
| 47 | n_known_poses = sum((p.requires_grad is False) for p in self.im_poses) |
| 48 | self.norm_pw_scale = (n_known_poses <= 1) |
| 49 | |
| 50 | def preset_intrinsics(self, known_intrinsics, msk=None): |
| 51 | if isinstance(known_intrinsics, torch.Tensor) and known_intrinsics.ndim == 2: |
| 52 | known_intrinsics = [known_intrinsics] |
| 53 | for K in known_intrinsics: |
| 54 | assert K.shape == (3, 3) |
| 55 | self.preset_focal([K.diagonal()[:2].mean() for K in known_intrinsics], msk) |
| 56 | self.preset_principal_point([K[:2, 2] for K in known_intrinsics], msk) |
| 57 | |
| 58 | def preset_focal(self, known_focals, msk=None): |
| 59 | for idx, focal in zip(self._get_msk_indices(msk), known_focals): |
| 60 | if self.verbose: |
| 61 | print(f' (setting focal #{idx} = {focal})') |
| 62 | self._no_grad(self._set_focal(idx, focal, force=True)) |
| 63 | |
| 64 | def preset_principal_point(self, known_pp, msk=None): |
| 65 | for idx, pp in zip(self._get_msk_indices(msk), known_pp): |
| 66 | if self.verbose: |
| 67 | print(f' (setting principal point #{idx} = {pp})') |
| 68 | self._no_grad(self._set_principal_point(idx, pp, force=True)) |
| 69 | |
| 70 | def _no_grad(self, tensor): |
| 71 | return tensor.requires_grad_(False) |
| 72 | |
| 73 | def _get_msk_indices(self, msk): |
| 74 | if msk is None: |