def add_gps_position(data, shot, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if "gps" in exif and "latitude" in exif["gps"] and "longitude" in exif["gps"]: lat = exif["gps"]["latitude"] lon = exif["gps"]["longitude"] if data.config.get("use_altitude_tag", False): alt = exif["gps"].get("altitude", 2.0) else: alt = 2.0 # Arbitrary constant value that will be used to align the reconstruction x, y, z = geo.topocentric_from_lla(lat, lon, alt, reflla["latitude"], reflla["longitude"], reflla["altitude"]) shot["gps_position"] = [x, y, z] shot["gps_dop"] = exif["gps"].get("dop", 15.0) else: shot["gps_position"] = [0.0, 0.0, 0.0] shot["gps_dop"] = 999999.0 shot["orientation"] = exif.get("orientation", 1) if "accelerometer" in exif: shot["accelerometer"] = exif["accelerometer"] if "compass" in exif: shot["compass"] = exif["compass"] if "capture_time" in exif: shot["capture_time"] = exif["capture_time"] if "skey" in exif: shot["skey"] = exif["skey"]
def add_gps_position(data, shot, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif and 'latitude' in exif['gps'] and 'longitude' in exif['gps']: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] if data.config.get('use_altitude_tag', False): alt = exif['gps'].get('altitude', 2.0) else: alt = 2.0 # Arbitrary constant value that will be used to align the reconstruction x, y, z = geo.topocentric_from_lla(lat, lon, alt, reflla['latitude'], reflla['longitude'], reflla['altitude']) shot['gps_position'] = [x, y, z] shot['gps_dop'] = exif['gps'].get('dop', 15.0) else: shot['gps_position'] = [0.0, 0.0, 0.0] shot['gps_dop'] = 999999.0 shot['orientation'] = exif.get('orientation', 1) if 'accelerometer' in exif: shot['accelerometer'] = exif['accelerometer'] if 'compass' in exif: shot['compass'] = exif['compass'] if 'capture_time' in exif: shot['capture_time'] = exif['capture_time'] if 'skey' in exif: shot['skey'] = exif['skey']
def match_candidates_by_distance(images, exifs, reference, max_neighbors, max_distance): """Find candidate matching pairs by GPS distance.""" if max_neighbors <= 0 and max_distance <= 0: return set() max_neighbors = max_neighbors or 99999999 max_distance = max_distance or 99999999. k = min(len(images), max_neighbors + 1) points = np.zeros((len(images), 3)) for i, image in enumerate(images): gps = exifs[image]['gps'] points[i] = geo.topocentric_from_lla(gps['latitude'], gps['longitude'], gps['altitude'], reference['latitude'], reference['longitude'], reference['altitude']) tree = spatial.cKDTree(points) pairs = set() for i, image in enumerate(images): distances, neighbors = tree.query(points[i], k=k, distance_upper_bound=max_distance) for j in neighbors: if i != j and j < len(images): pairs.add(tuple(sorted((images[i], images[j])))) return pairs
def add_cluster_neighbors(positions, labels, centers, max_distance): reference = np.mean(positions, 0) topocentrics = [] for position in positions: x, y, z = geo.topocentric_from_lla( position[0], position[1], 0, reference[0], reference[1], 0) topocentrics.append([x, y]) topocentrics = np.array(topocentrics) topo_tree = spatial.cKDTree(topocentrics) clusters = [] for label in np.arange(centers.shape[0]): cluster_indices = np.where(labels.ravel() == label)[0] neighbors = [] for i in cluster_indices: neighbors.extend( topo_tree.query_ball_point(topocentrics[i], max_distance)) cluster = list(np.union1d(cluster_indices, neighbors)) clusters.append(cluster) return clusters
def _read_ground_control_points_list_line(line, projection, reference_lla, exif): words = line.split() easting, northing, alt, pixel_x, pixel_y = map(float, words[:5]) shot_id = words[5] # Convert 3D coordinates if projection is not None: lon, lat = projection(easting, northing, inverse=True) else: lon, lat = easting, northing x, y, z = geo.topocentric_from_lla( lat, lon, alt, reference_lla['latitude'], reference_lla['longitude'], reference_lla['altitude']) # Convert 2D coordinates d = exif[shot_id] coordinates = features.normalized_image_coordinates( np.array([[pixel_x, pixel_y]]), d['width'], d['height'])[0] o = types.GroundControlPointObservation() o.lla = np.array([lat, lon, alt]) o.coordinates = np.array([x, y, z]) o.shot_id = shot_id o.shot_coordinates = coordinates return o
def get_image_metadata(data, image): metadata = types.ShotMetadata() exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif and 'latitude' in exif['gps'] and 'longitude' in exif['gps']: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] if data.config.get('use_altitude_tag', False): alt = exif['gps'].get('altitude', 2.0) else: alt = 2.0 # Arbitrary constant value that will be used to align the reconstruction x, y, z = geo.topocentric_from_lla(lat, lon, alt, reflla['latitude'], reflla['longitude'], reflla['altitude']) metadata.gps_position = [x, y, z] metadata.gps_dop = exif['gps'].get('dop', 15.0) else: metadata.gps_position = [0.0, 0.0, 0.0] metadata.gps_dop = 999999.0 metadata.orientation = exif.get('orientation', 1) if 'accelerometer' in exif: metadata.accelerometer = exif['accelerometer'] if 'compass' in exif: metadata.compass = exif['compass'] if 'capture_time' in exif: metadata.capture_time = exif['capture_time'] if 'skey' in exif: metadata.skey = exif['skey'] return metadata
def match_candidates_by_distance(images, exifs, reference, max_neighbors, max_distance): """Find candidate matching pairs by GPS distance. The GPS altitude is ignored because we want images of the same position at different altitudes to be matched together. Otherwise, for drone datasets, flights at different altitudes do not get matched. """ if max_neighbors <= 0 and max_distance <= 0: return set() max_neighbors = max_neighbors or 99999999 max_distance = max_distance or 99999999. k = min(len(images), max_neighbors + 1) points = np.zeros((len(images), 3)) for i, image in enumerate(images): gps = exifs[image]['gps'] points[i] = geo.topocentric_from_lla(gps['latitude'], gps['longitude'], 0, reference['latitude'], reference['longitude'], 0) tree = spatial.cKDTree(points) pairs = set() for i, image in enumerate(images): distances, neighbors = tree.query(points[i], k=k, distance_upper_bound=max_distance) for j in neighbors: if i != j and j < len(images): pairs.add(tuple(sorted((images[i], images[j])))) return pairs
def add_cluster_neighbors(positions, labels, centers, max_distance): reference = np.mean(positions, 0) topocentrics = [] for position in positions: x, y, z = geo.topocentric_from_lla(position[0], position[1], 0, reference[0], reference[1], 0) topocentrics.append([x, y]) topocentrics = np.array(topocentrics) topo_tree = spatial.cKDTree(topocentrics) clusters = [] for label in np.arange(centers.shape[0]): cluster_indices = np.where(labels == label)[0] neighbors = [] for i in cluster_indices: neighbors.extend( topo_tree.query_ball_point(topocentrics[i], max_distance)) cluster = list(np.union1d(cluster_indices, neighbors)) clusters.append(cluster) return clusters
def add_gps_position(data, shot, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif and 'latitude' in exif['gps'] and 'longitude' in exif['gps']: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] alt = 2.0 #exif['gps'].get('altitude', 0) x, y, z = geo.topocentric_from_lla(lat, lon, alt, reflla['latitude'], reflla['longitude'], reflla['altitude']) shot['gps_position'] = [x, y, z] shot['gps_dop'] = exif['gps'].get('dop', 15.0) else: shot['gps_position'] = [0.0, 0.0, 0.0] shot['gps_dop'] = 999999.0 shot['orientation'] = exif.get('orientation', 1) if 'accelerometer' in exif: shot['accelerometer'] = exif['accelerometer'] if 'compass' in exif: shot['compass'] = exif['compass'] if 'capture_time' in exif: shot['capture_time'] = exif['capture_time'] if 'skey' in exif: shot['skey'] = exif['skey']
def match_candidates_by_distance(images, exifs, reference, max_neighbors, max_distance): """Find candidate matching pairs by GPS distance.""" if max_neighbors <= 0 and max_distance <= 0: return set() max_neighbors = max_neighbors or 99999999 max_distance = max_distance or 99999999. k = min(len(images), max_neighbors + 1) points = np.zeros((len(images), 3)) for i, image in enumerate(images): gps = exifs[image]['gps'] points[i] = geo.topocentric_from_lla( gps['latitude'], gps['longitude'], gps['altitude'], reference['latitude'], reference['longitude'], reference['altitude']) tree = spatial.cKDTree(points) pairs = set() for i, image in enumerate(images): distances, neighbors = tree.query( points[i], k=k, distance_upper_bound=max_distance) for j in neighbors: if i != j and j < len(images): pairs.add(tuple(sorted((images[i], images[j])))) return pairs
def add_gps_position(data, shot, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif and 'latitude' in exif['gps'] and 'longitude' in exif[ 'gps']: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] if data.config.get('use_altitude_tag', False): alt = exif['gps'].get('altitude', 2.0) else: alt = 2.0 # Arbitrary constant value that will be used to align the reconstruction x, y, z = geo.topocentric_from_lla(lat, lon, alt, reflla['latitude'], reflla['longitude'], reflla['altitude']) shot['gps_position'] = [x, y, z] shot['gps_dop'] = exif['gps'].get('dop', 15.0) else: shot['gps_position'] = [0.0, 0.0, 0.0] shot['gps_dop'] = 999999.0 shot['orientation'] = exif.get('orientation', 1) if 'accelerometer' in exif: shot['accelerometer'] = exif['accelerometer'] if 'compass' in exif: shot['compass'] = exif['compass'] if 'capture_time' in exif: shot['capture_time'] = exif['capture_time'] if 'skey' in exif: shot['skey'] = exif['skey']
def test_ecef_lla_topocentric_consistency() -> None: lla_ref = [46.5, 6.5, 400] lla_before = [46.5274109, 6.5722075, 402.16] enu = geo.topocentric_from_lla(lla_before[0], lla_before[1], lla_before[2], lla_ref[0], lla_ref[1], lla_ref[2]) lla_after = geo.lla_from_topocentric(enu[0], enu[1], enu[2], lla_ref[0], lla_ref[1], lla_ref[2]) assert np.allclose(lla_after, lla_before)
def _load_topocentric_gps_points(): topocentric_gps_points_dict = {} with open("gps_list.txt") as fin: gps_points_dict = io.read_gps_points_list(fin) with io.open_rt("reference_lla.json") as fin: reflla = io.json_load(fin) for key, value in gps_points_dict.items(): x, y, z = geo.topocentric_from_lla( value[0], value[1], value[2], reflla['latitude'], reflla['longitude'], reflla['altitude']) topocentric_gps_points_dict[key] = (x, y, z) return topocentric_gps_points_dict
def test_ecef_lla_topocentric_consistency(): lla_ref = [46.5, 6.5, 400] lla_before = [46.5274109, 6.5722075, 402.16] enu = geo.topocentric_from_lla(lla_before[0], lla_before[1], lla_before[2], lla_ref[0], lla_ref[1], lla_ref[2]) lla_after = geo.lla_from_topocentric(enu[0], enu[1], enu[2], lla_ref[0], lla_ref[1], lla_ref[2]) assert np.allclose(lla_after, lla_before)
def add_gps_position(data, reconstruction, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] alt = 2.0 #exif['gps'].get('altitude', 0) x, y, z = geo.topocentric_from_lla(lat, lon, alt, *reflla) reconstruction['shots'][image]['gps_position'] = [x, y, z] reconstruction['shots'][image]['gps_dop'] = exif['gps'].get( 'dop', 15.0) else: reconstruction['shots'][image]['gps_position'] = [0.0, 0.0, 0.0] reconstruction['shots'][image]['gps_dop'] = 999999.0 reconstruction['shots'][image]['exif_orientation'] = exif.get( 'orientation', 1)
def _read_ground_control_points_list_line(line, reference_lla, exif): words = line.split() lat, lon, alt, pixel_x, pixel_y = map(float, words[:5]) shot_id = words[5] x, y, z = geo.topocentric_from_lla( lat, lon, alt, reference_lla['latitude'], reference_lla['longitude'], reference_lla['altitude']) d = exif[shot_id] o = types.GroundControlPointObservation() o.lla = np.array([lat, lon, alt]) o.coordinates = np.array([x, y, z]) o.shot_id = shot_id o.shot_coordinates = features.normalized_image_coordinates( np.array([[pixel_x, pixel_y]]), d['width'], d['height'])[0] return o
def add_gps_position(data, reconstruction, image): exif = data.load_exif(image) reflla = data.load_reference_lla() if 'gps' in exif and 'latitude' in exif['gps'] and 'longitude' in exif['gps']: lat = exif['gps']['latitude'] lon = exif['gps']['longitude'] alt = 2.0 #exif['gps'].get('altitude', 0) x, y, z = geo.topocentric_from_lla(lat, lon, alt, *reflla) reconstruction['shots'][image]['gps_position'] = [x, y, z] reconstruction['shots'][image]['gps_dop'] = exif['gps'].get('dop', 15.0) else: reconstruction['shots'][image]['gps_position'] = [0.0, 0.0, 0.0] reconstruction['shots'][image]['gps_dop'] = 999999.0 reconstruction['shots'][image]['exif_orientation'] = exif.get('orientation', 1) if 'accelerometer' in exif: reconstruction['shots'][image]['accelerometer'] = exif['accelerometer'] if 'compass' in exif: reconstruction['shots'][image]['compass'] = exif['compass']