Add camera frames and frustums to the scene.
(extrinsics, images_: np.ndarray)
| 145 | frustums: List[viser.CameraFrustumHandle] = [] |
| 146 | |
| 147 | def visualize_frames(extrinsics, images_: np.ndarray) -> None: |
| 148 | """Add camera frames and frustums to the scene.""" |
| 149 | for f in frames: |
| 150 | f.remove() |
| 151 | frames.clear() |
| 152 | for fr in frustums: |
| 153 | fr.remove() |
| 154 | frustums.clear() |
| 155 | |
| 156 | def attach_callback(frustum: viser.CameraFrustumHandle, frame: viser.FrameHandle) -> None: |
| 157 | @frustum.on_click |
| 158 | def _(_) -> None: |
| 159 | for client in server.get_clients().values(): |
| 160 | client.camera.wxyz = frame.wxyz |
| 161 | client.camera.position = frame.position |
| 162 | |
| 163 | for img_id in tqdm(range(S)): |
| 164 | cam2world_3x4 = extrinsics[img_id] |
| 165 | T_world_camera = tf.SE3.from_matrix(cam2world_3x4) |
| 166 | |
| 167 | frame_axis = server.scene.add_frame( |
| 168 | f"frame_{img_id}", |
| 169 | wxyz=T_world_camera.rotation().wxyz, |
| 170 | position=T_world_camera.translation(), |
| 171 | axes_length=0.05, |
| 172 | axes_radius=0.002, |
| 173 | origin_radius=0.002, |
| 174 | ) |
| 175 | frames.append(frame_axis) |
| 176 | |
| 177 | img = images_[img_id] |
| 178 | img = (img.transpose(1, 2, 0) * 255).astype(np.uint8) |
| 179 | h, w = img.shape[:2] |
| 180 | |
| 181 | fy = 1.1 * h |
| 182 | fov = 2 * np.arctan2(h / 2, fy) |
| 183 | |
| 184 | frustum_cam = server.scene.add_camera_frustum( |
| 185 | f"frame_{img_id}/frustum", |
| 186 | fov=fov, |
| 187 | aspect=w / h, |
| 188 | scale=0.05, |
| 189 | image=img, |
| 190 | line_width=1.0 |
| 191 | ) |
| 192 | frustums.append(frustum_cam) |
| 193 | attach_callback(frustum_cam, frame_axis) |
| 194 | |
| 195 | def update_point_cloud() -> None: |
| 196 | """Update point cloud based on current GUI selections.""" |
no test coverage detected