def SfM_reconstruct(src): # incremental_reconstruction from opensfm.dataset import DataSet from opensfm.reconstruction import (tracking, compute_image_pairs, bootstrap_reconstruction, grow_reconstruction) data = DataSet(src); result = [] gcp = data.load_ground_control_points() tracks = data.load_tracks_manager() imgs = tracks.get_shot_ids() if not data.reference_lla_exists(): data.invent_reference_lla(imgs) camera_priors = data.load_camera_models() common_tracks = tracking.all_common_tracks(tracks) pairs = compute_image_pairs(common_tracks, camera_priors, data) imgs = set(imgs); report = {'candidate_image_pairs': len(pairs)} for im1, im2 in pairs: if im1 in imgs and im2 in imgs: report[im1+' & '+im2] = log = {} v, p1, p2 = common_tracks[im1, im2] rec, log['bootstrap'] = bootstrap_reconstruction( data, tracks, camera_priors, im1, im2, p1, p2) if rec: imgs.remove(im1); imgs.remove(im2) rec, log['grow'] = grow_reconstruction( data, tracks, rec, imgs, camera_priors, gcp) result.append(rec) result = sorted(result, key=lambda x: -len(x.shots)) data.save_reconstruction(result) report['not_reconstructed_images'] = list(imgs) with open(f'{src}/reports/reconstruction.json','w') as f: json.dump(report, f, indent=4)
def run_dataset(data: DataSet): """ Split the dataset into smaller submodels. """ meta_data = MetaDataSet(data.data_path) meta_data.remove_submodels() data.invent_reference_lla() _create_image_list(data, meta_data) if meta_data.image_groups_exists(): _read_image_groups(meta_data) else: _cluster_images(meta_data, data.config["submodel_size"]) _add_cluster_neighbors(meta_data, data.config["submodel_overlap"]) _save_clusters_geojson(meta_data) _save_cluster_neighbors_geojson(meta_data) meta_data.create_submodels(meta_data.load_clusters_with_neighbors())
def propose_subset_dataset_from_instances( data: DataSet, rig_instances: Dict[str, TRigInstance], name: str ) -> Iterable[Tuple[DataSet, List[List[Tuple[str, str]]]]]: """Given a list of images grouped by rigs instances, infitely propose random subset of images and create a dataset subset with the provided name from them. Returns : Yield infinitely DataSet containing a subset of images containing enough rig instances """ per_rig_camera_group = group_instances(rig_instances) if not data.reference_lla_exists(): data.invent_reference_lla() reference = data.load_reference() instances_to_pick = {} for key, instances in per_rig_camera_group.items(): # build GPS look-up tree gpses = [] for i, instance in enumerate(instances): all_gps = [] for image, _ in instance: gps = data.load_exif(image)["gps"] all_gps.append( reference.to_topocentric(gps["latitude"], gps["longitude"], 0) ) gpses.append((i, np.average(np.array(all_gps), axis=0))) tree = spatial.cKDTree([x[1] for x in gpses]) # build NN-graph and split by connected components nn = 6 instances_graph = nx.Graph() for i, gps in gpses: distances, neighbors = tree.query(gps, k=nn) for d, n in zip(distances, neighbors): if i == n: continue instances_graph.add_edge(i, n, weight=d) all_components = sorted( nx.algorithms.components.connected_components(instances_graph), key=len, reverse=True, ) logger.info(f"Found {len(all_components)} connected components") # keep the biggest one biggest_component = all_components[0] logger.info(f"Best component has {len(biggest_component)} instances") instances_to_pick[key] = biggest_component random.seed(42) while True: total_instances = [] subset_images = [] for key, instances in instances_to_pick.items(): all_instances = per_rig_camera_group[key] instances_sorted = sorted( [all_instances[i] for i in instances], key=lambda x: data.load_exif(x[0][0])["capture_time"], ) subset_size = data.config["rig_calibration_subset_size"] random_index = random.randint(0, len(instances_sorted) - 1) instances_calibrate = instances_sorted[ max([0, random_index - int(subset_size / 2)]) : min( [random_index + int(subset_size / 2), len(instances_sorted) - 1] ) ] for instance in instances_calibrate: subset_images += [x[0] for x in instance] total_instances += instances_calibrate data.io_handler.rm_if_exist(os.path.join(data.data_path, name)) yield data.subset(name, subset_images), total_instances