def _reconstruction_from_rigs_and_assignments(data: DataSetBase): assignments = data.load_rig_assignments() models = data.load_rig_models() if not data.reference_lla_exists(): data.invent_reference_lla() base_rotation = np.zeros(3) reconstructions = [] for rig_id, instances in assignments.items(): rig_cameras = models[rig_id]["rig_cameras"] reconstruction = types.Reconstruction() reconstruction.cameras = data.load_camera_models() for instance in instances: for image, camera_id in instance: rig_camera = rig_cameras[camera_id] rig_pose = pygeometry.Pose(base_rotation) rig_pose.set_origin( orec.get_image_metadata(data, image).gps_position.value) rig_camera_pose = pygeometry.Pose(rig_camera["rotation"], rig_camera["translation"]) d = data.load_exif(image) shot = reconstruction.create_shot(image, d["camera"]) shot.pose = rig_camera_pose.compose(rig_pose) shot.metadata = orec.get_image_metadata(data, image) reconstructions.append(reconstruction) return reconstructions
def incremental_reconstruction( data: DataSetBase, tracks_manager: pysfm.TracksManager ) -> Tuple[Dict[str, Any], List[types.Reconstruction]]: """Run the entire incremental reconstruction pipeline.""" logger.info("Starting incremental reconstruction") report = {} chrono = Chronometer() images = tracks_manager.get_shot_ids() if not data.reference_lla_exists(): data.invent_reference_lla(images) remaining_images = set(images) gcp = data.load_ground_control_points() common_tracks = tracking.all_common_tracks(tracks_manager) reconstructions = [] pairs = compute_image_pairs(common_tracks, data) chrono.lap("compute_image_pairs") report["num_candidate_image_pairs"] = len(pairs) report["reconstructions"] = [] for im1, im2 in pairs: if im1 in remaining_images and im2 in remaining_images: rec_report = {} report["reconstructions"].append(rec_report) _, p1, p2 = common_tracks[im1, im2] reconstruction, rec_report["bootstrap"] = bootstrap_reconstruction( data, tracks_manager, im1, im2, p1, p2 ) if reconstruction: remaining_images -= set(reconstruction.shots) reconstruction, rec_report["grow"] = grow_reconstruction( data, tracks_manager, reconstruction, remaining_images, gcp, ) reconstructions.append(reconstruction) reconstructions = sorted(reconstructions, key=lambda x: -len(x.shots)) for k, r in enumerate(reconstructions): logger.info( "Reconstruction {}: {} images, {} points".format( k, len(r.shots), len(r.points) ) ) logger.info("{} partial reconstructions in total.".format(len(reconstructions))) chrono.lap("compute_reconstructions") report["wall_times"] = dict(chrono.lap_times()) report["not_reconstructed_images"] = list(remaining_images) return report, reconstructions
def match_candidates_from_metadata( images_ref: List[str], images_cand: List[str], exifs: Dict[str, Any], data: DataSetBase, config_override: Dict[str, Any], ) -> Tuple[List[Tuple[str, str]], Dict[str, Any]]: """Compute candidate matching pairs between between images_ref and images_cand Returns a list of pairs (im1, im2) such that (im1 in images_ref) is true. Returned pairs are unique given that (i, j) == (j, i). """ overriden_config = data.config.copy() overriden_config.update(config_override) max_distance = overriden_config["matching_gps_distance"] gps_neighbors = overriden_config["matching_gps_neighbors"] time_neighbors = overriden_config["matching_time_neighbors"] order_neighbors = overriden_config["matching_order_neighbors"] bow_neighbors = overriden_config["matching_bow_neighbors"] bow_gps_distance = overriden_config["matching_bow_gps_distance"] bow_gps_neighbors = overriden_config["matching_bow_gps_neighbors"] bow_other_cameras = overriden_config["matching_bow_other_cameras"] vlad_neighbors = overriden_config["matching_vlad_neighbors"] vlad_gps_distance = overriden_config["matching_vlad_gps_distance"] vlad_gps_neighbors = overriden_config["matching_vlad_gps_neighbors"] vlad_other_cameras = overriden_config["matching_vlad_other_cameras"] if not data.reference_lla_exists(): data.invent_reference_lla() reference = data.load_reference() if not all(map(has_gps_info, exifs.values())): if gps_neighbors != 0: logger.warn("Not all images have GPS info. " "Disabling matching_gps_neighbors.") gps_neighbors = 0 max_distance = 0 images_ref.sort() if (max_distance == gps_neighbors == time_neighbors == order_neighbors == bow_neighbors == vlad_neighbors == 0): # All pair selection strategies deactivated so we match all pairs d = set() t = set() o = set() b = set() v = set() pairs = { sorted_pair(i, j) for i in images_ref for j in images_cand if i != j } else: d = match_candidates_by_distance(images_ref, images_cand, exifs, reference, gps_neighbors, max_distance) t = match_candidates_by_time(images_ref, images_cand, exifs, time_neighbors) o = match_candidates_by_order(images_ref, images_cand, order_neighbors) b = match_candidates_with_bow( data, images_ref, images_cand, exifs, reference, bow_neighbors, bow_gps_distance, bow_gps_neighbors, bow_other_cameras, ) v = match_candidates_with_vlad( data, images_ref, images_cand, exifs, reference, vlad_neighbors, vlad_gps_distance, vlad_gps_neighbors, vlad_other_cameras, {}, ) pairs = d | t | o | set(b) | set(v) pairs = ordered_pairs(pairs, images_ref) report = { "num_pairs_distance": len(d), "num_pairs_time": len(t), "num_pairs_order": len(o), "num_pairs_bow": len(b), "num_pairs_vlad": len(v), } return pairs, report