def create_subset_dataset_from_instances(data: DataSet, instances_per_rig, name): """Given a list of images grouped by rigs instances, pick a subset of images and create a dataset subset with the provided name from them. Returns : A DataSet containing a subset of images containing enough rig instances """ subset_images = [] for instances in instances_per_rig.values(): instances_sorted = sorted( instances, key=lambda x: data.load_exif(x[0][0])["capture_time"]) subset_size = data.config["rig_calibration_subset_size"] middle = len(instances_sorted) / 2 instances_calibrate = instances_sorted[max( [0, middle - int(subset_size / 2)] ):min([middle + int(subset_size / 2 ), len(instances_sorted) - 1])] for instance in instances_calibrate: subset_images += [x[0] for x in instance] return data.subset(name, subset_images)
def SfM_export_pos(src, dop=0.1, tsv='image_geocoords.tsv'): rename_rec(src) dif = [] gjs = {} # for sfm SfM_cmd(src, f'export_geocoords --image-positions --proj="{LLA}"') rename_rec(src) geo = load_sort_save(f'{src}/{tsv}', a=1) # sort with open(src + '/geo.txt', 'w') as f: f.writelines([LLA + '\n'] + geo[1:]) from opensfm.dataset import DataSet data = DataSet(src) ref = data.load_reference() for v in geo[1:]: # skip 1st-row im, *v = v.split() v = np.float64(v)[[1, 0, 2]] o = [*data.load_exif(im)['gps'].values()][:3] # lat,lon,alt ov = ref.to_topocentric(*v) - np.array(ref.to_topocentric(*o)) gjs[im] = { 'gps': dict(latitude=v[0], longitude=v[1], altitude=v[2], dop=dop) } dif += [f'{im} lla={v} exif={o}\tdif={ov.tolist()}\n'] with open(f'{src}/{tsv[:-4]}.dif.txt', 'w') as f: f.writelines(dif) with open(src + '/geo.json', 'w') as f: json.dump(gjs, f, indent=4)
def _create_image_list(data: DataSet, meta_data): ills = [] for image in data.images(): exif = data.load_exif(image) if ("gps" not in exif or "latitude" not in exif["gps"] or "longitude" not in exif["gps"]): logger.warning("Skipping {} because of missing GPS".format(image)) continue lat = exif["gps"]["latitude"] lon = exif["gps"]["longitude"] ills.append((image, lat, lon)) meta_data.create_image_list(ills)
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