Exemple #1
0
def scene_synthetic_triangulation() -> synthetic_scene.SyntheticInputData:
    np.random.seed(42)
    reference = geo.TopocentricConverter(47.0, 6.0, 0)
    data = synthetic_examples.synthetic_circle_scene(reference)

    maximum_depth = 40
    projection_noise = 1.0
    gps_noise = 0.1
    imu_noise = 1.0
    gcp_noise = (0.0, 0.0)

    gcps_count = 10
    gcps_shift = [10.0, 0.0, 100.0]

    return synthetic_scene.SyntheticInputData(
        data.get_reconstruction(),
        reference,
        maximum_depth,
        projection_noise,
        gps_noise,
        imu_noise,
        gcp_noise,
        False,
        gcps_count,
        gcps_shift,
    )
Exemple #2
0
    def load_reference(self) -> geo.TopocentricConverter:
        """Load reference as a topocentric converter."""
        with self.io_handler.open_rt(self._reference_lla_path()) as fin:
            lla = io.json_load(fin)

        return geo.TopocentricConverter(lla["latitude"], lla["longitude"],
                                        lla["altitude"])
def generate_exifs(reconstruction, gps_noise, speed_ms=10):
    """Generate fake exif metadata from the reconstruction."""
    previous_pose = None
    previous_time = 0
    exifs = {}
    reference = geo.TopocentricConverter(0, 0, 0)
    for shot_name in sorted(reconstruction.shots.keys()):
        shot = reconstruction.shots[shot_name]
        exif = {}
        exif['width'] = shot.camera.width
        exif['height'] = shot.camera.height
        exif['focal_ratio'] = shot.camera.focal
        exif['camera'] = str(shot.camera.id)
        exif['make'] = str(shot.camera.id)

        pose = shot.pose.get_origin()

        if previous_pose is not None:
            previous_time += np.linalg.norm(pose-previous_pose)*speed_ms
        previous_pose = pose
        exif['capture_time'] = previous_time

        perturb_points([pose], [gps_noise, gps_noise, gps_noise])

        _, _, _, comp = rc.shot_lla_and_compass(shot, reference)
        lat, lon, alt = reference.to_lla(*pose)

        exif['gps'] = {}
        exif['gps']['latitude'] = lat
        exif['gps']['longitude'] = lon
        exif['gps']['altitude'] = alt
        exif['gps']['dop'] = gps_noise
        exif['compass'] = {'angle': comp}
        exifs[shot_name] = exif
    return exifs
Exemple #4
0
def add_cluster_neighbors(positions, labels, centers, max_distance):
    reflla = np.mean(positions, 0)
    reference = geo.TopocentricConverter(reflla[0], reflla[1], 0)

    topocentrics = []
    for position in positions:
        x, y, z = reference.to_topocentric(position[0], position[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
Exemple #5
0
def reconstruction_from_json(obj: Dict[str, Any]) -> types.Reconstruction:
    """
    Read a reconstruction from a json object
    """
    reconstruction = types.Reconstruction()

    # Extract cameras
    for key, value in obj["cameras"].items():
        camera = camera_from_json(key, value)
        reconstruction.add_camera(camera)

    # Extract camera biases
    if "biases" in obj:
        for key, value in obj["biases"].items():
            transform = bias_from_json(value)
            reconstruction.set_bias(key, transform)

    # Extract rig models
    if "rig_cameras" in obj:
        for key, value in obj["rig_cameras"].items():
            reconstruction.add_rig_camera(rig_camera_from_json(key, value))

    # Extract rig instances from shots
    if "rig_instances" in obj:
        for key, value in obj["rig_instances"].items():
            rig_instance_from_json(reconstruction, key, value)

    # Extract shots
    rig_shots = rig_instance_camera_per_shot(obj)
    for key, value in obj["shots"].items():
        shot_in_reconstruction_from_json(
            reconstruction,
            key,
            value,
            rig_camera_id=rig_shots[key][1] if key in rig_shots else None,
            rig_instance_id=rig_shots[key][0] if key in rig_shots else None,
            is_pano_shot=False,
        )

    # Extract points
    if "points" in obj:
        for key, value in obj["points"].items():
            point_from_json(reconstruction, key, value)

    # Extract pano_shots
    if "pano_shots" in obj:
        for key, value in obj["pano_shots"].items():
            shot_in_reconstruction_from_json(
                reconstruction, key, value, is_pano_shot=True
            )

    # Extract reference topocentric frame
    if "reference_lla" in obj:
        lla = obj["reference_lla"]
        reconstruction.reference = geo.TopocentricConverter(
            lla["latitude"], lla["longitude"], lla["altitude"]
        )

    return reconstruction
Exemple #6
0
def scene_synthetic_cube():
    np.random.seed(42)
    data = synthetic_examples.synthetic_cube_scene()

    reference = geo.TopocentricConverter(47.0, 6.0, 0)
    reconstruction = data.get_reconstruction()
    input_data = synthetic_scene.SyntheticInputData(reconstruction, reference,
                                                    40, 0.0, 0.0, False)
    return reconstruction, input_data.tracks_manager
Exemple #7
0
def test_get_gps_point() -> None:
    reference = geo.TopocentricConverter(0, 0, 0)
    exifs = {}
    exifs["gps"] = {
        "latitude": 0.0001,
        "longitude": 0.0001,
        "altitude": 100.0,
    }
    origin, direction = pairs_selection.get_gps_point(exifs, reference)
    assert np.allclose(origin, [[11.131, 11.057, 0.0]], atol=1e-3)
    assert np.allclose(direction, [[0, 0, 1]])
Exemple #8
0
def reconstruction_from_json(obj: t.Dict[str, t.Any]):
    """
    Read a reconstruction from a json object
    """
    reconstruction = types.Reconstruction()

    # Extract cameras
    for key, value in obj["cameras"].items():
        camera = camera_from_json(key, value)
        reconstruction.add_camera(camera)

    # Extract rig models
    if "rig_cameras" in obj:
        for key, value in obj["rig_cameras"].items():
            reconstruction.add_rig_camera(rig_camera_from_json(key, value))

    # Extract shots
    for key, value in obj["shots"].items():
        shot_in_reconstruction_from_json(reconstruction, key, value)

    # Extract rig instances from shots
    if "rig_instances" in obj:
        for key, value in obj["rig_instances"].items():
            rig_instance_from_json(reconstruction, key, value)

    # Extract points
    if "points" in obj:
        for key, value in obj["points"].items():
            point_from_json(reconstruction, key, value)

    # Extract pano_shots
    if "pano_shots" in obj:
        for key, value in obj["pano_shots"].items():
            is_pano_shot = True
            shot_in_reconstruction_from_json(reconstruction, key, value,
                                             is_pano_shot)

    # Extract main and unit shots
    if "main_shot" in obj:
        # pyre-fixme[16]: `types.Reconstruction` has no attribute `main_shot`
        reconstruction.main_shot = obj["main_shot"]
    if "unit_shot" in obj:
        # pyre-fixme[16]: `types.Reconstruction` has no attribute `unit_shot`
        reconstruction.unit_shot = obj["unit_shot"]

    # Extract reference topocentric frame
    if "reference_lla" in obj:
        lla = obj["reference_lla"]
        reconstruction.reference = geo.TopocentricConverter(
            lla["latitude"], lla["longitude"], lla["altitude"])

    return reconstruction
Exemple #9
0
def test_read_ground_control_points():
    text = """
{
  "points": [
    {
      "id": "1",
      "position": {
        "latitude": 52.519134104,
        "longitude": 13.400740745,
        "altitude": 12.0792090446
      },
      "observations": [
        {
          "shot_id": "01.jpg",
          "projection": [0.7153, 0.5787]
        },
        {
          "shot_id": "02.jpg",
          "projection": [0.8085, 0.3831]
        }
      ]
    },
    {
      "id": "2",
      "position": {
        "latitude": 52.519251158,
        "longitude": 13.400502446,
        "altitude": 16.7021233002
      },
      "observations": [
        {
          "shot_id": "01.jpg",
          "projection": [0.2346, 0.4628]
        }
      ]
    }
  ]
}    
    """
    fp = StringIO(text)
    reference = geo.TopocentricConverter(52.51913, 13.4007, 0)

    points = io.read_ground_control_points(fp, reference)
    assert len(points) == 2

    a, b = (len(point.observations) for point in points)
    assert min(a, b) == 1
    assert max(a, b) == 2
Exemple #10
0
def generate_exifs(reconstruction, gps_noise, speed_ms=10):
    """
    Return extracted exif information, as dictionary, usually with fields:

    ================  =====  ===================================
    Field             Type   Description
    ================  =====  ===================================
    width             int    Width of image, in pixels
    height            int    Height of image, in pixels
    focal_prior       float  Focal length (real) / sensor width
    ================  =====  ===================================

    :param image: Image name, with extension (i.e. 123.jpg)
    """
    previous_pose = None
    previous_time = 0
    exifs = {}
    reference = geo.TopocentricConverter(0, 0, 0)
    for shot_name in sorted(reconstruction.shots.keys()):
        shot = reconstruction.shots[shot_name]
        exif = {}
        exif['width'] = shot.camera.width
        exif['height'] = shot.camera.height
        exif['focal_prior'] = shot.camera.focal_prior
        exif['camera'] = str(shot.camera.id)
        exif['make'] = str(shot.camera.id)

        pose = shot.pose.get_origin()

        if previous_pose is not None:
            previous_time += np.linalg.norm(pose - previous_pose) * speed_ms
            previous_pose = pose
        exif['capture_time'] = previous_time

        perturb_points([pose], [gps_noise, gps_noise, gps_noise])

        shot_copy = copy.deepcopy(shot)
        shot_copy.pose.set_origin(pose)
        lat, lon, alt, comp = rc.shot_lla_and_compass(shot_copy, reference)

        exif['gps'] = {}
        exif['gps']['latitude'] = lat
        exif['gps']['longitude'] = lon
        exif['gps']['altitude'] = alt
        exif['gps']['dop'] = gps_noise
        exif['compass'] = {'angle': comp}
        exifs[shot_name] = exif
    return exifs
Exemple #11
0
def reconstruction_from_json(obj):
    """
    Read a reconstruction from a json object
    """
    reconstruction = types.Reconstruction()

    # Extract alignment meta-data
    reconstruction.alignment = alignment_from_json(obj.get('alignment', None))

    # Extract cameras
    for key, value in iteritems(obj['cameras']):
        camera = camera_from_json(key, value)
        reconstruction.add_camera(camera)

    # Extract shots
    for key, value in iteritems(obj['shots']):
        shot = shot_from_json(key, value, reconstruction.cameras)
        reconstruction.add_shot(shot)

    # Extract points
    if 'points' in obj:
        for key, value in iteritems(obj['points']):
            point = point_from_json(key, value)
            reconstruction.add_point(point)

    # Extract pano_shots
    if 'pano_shots' in obj:
        reconstruction.pano_shots = {}
        for key, value in iteritems(obj['pano_shots']):
            shot = shot_from_json(key, value, reconstruction.cameras)
            reconstruction.pano_shots[shot.id] = shot

    # Extract main and unit shots
    if 'main_shot' in obj:
        reconstruction.main_shot = obj['main_shot']
    if 'main_shots' in obj:
        reconstruction.main_shots = obj['main_shots']
    if 'unit_shot' in obj:
        reconstruction.unit_shot = obj['unit_shot']

    # Extract reference topocentric frame
    if 'reference_lla' in obj:
        lla = obj['reference_lla']
        reconstruction.reference = geo.TopocentricConverter(
            lla['latitude'], lla['longitude'], lla['altitude'])

    return reconstruction
Exemple #12
0
def test_read_gcp_list():
    text = """WGS84
13.400740745 52.519134104 12.0792090446 2335.0 1416.7 01.jpg
13.400740745 52.519134104 12.0792090446 2639.1 938.0 02.jpg
13.400502446 52.519251158 16.7021233002 766.0 1133.1 01.jpg
    """
    fp = StringIO(text)
    reference = geo.TopocentricConverter(52.51913, 13.4007, 0)
    images = ["01.jpg", "02.jpg"]
    exif = {i: {"width": 3000, "height": 2000} for i in images}

    points = io.read_gcp_list(fp, reference, exif)
    assert len(points) == 2

    a, b = (len(point.observations) for point in points)
    assert min(a, b) == 1
    assert max(a, b) == 2
Exemple #13
0
def scene_synthetic_rig() -> synthetic_scene.SyntheticInputData:
    np.random.seed(42)
    data = synthetic_examples.synthetic_rig_scene()

    maximum_depth = 40
    projection_noise = 1.0
    gps_noise = 0.1

    reference = geo.TopocentricConverter(47.0, 6.0, 0)
    return synthetic_scene.SyntheticInputData(
        data.get_reconstruction(),
        reference,
        maximum_depth,
        projection_noise,
        gps_noise,
        False,
    )
Exemple #14
0
def reconstruction_from_json(obj):
    """
    Read a reconstruction from a json object
    """
    reconstruction = types.Reconstruction()

    # Extract cameras
    for key, value in obj["cameras"].items():
        camera = camera_from_json(key, value)
        reconstruction.add_camera(camera)

    # Extract shots
    for key, value in obj["shots"].items():
        shot_from_json(reconstruction, key, value)

    # Extract points
    if "points" in obj:
        for key, value in obj["points"].items():
            point_from_json(reconstruction, key, value)

    # Extract pano_shots
    if "pano_shots" in obj:
        for key, value in obj["pano_shots"].items():
            is_pano_shot = True
            shot_from_json(reconstruction, key, value, is_pano_shot)

    # Extract main and unit shots
    if "main_shot" in obj:
        reconstruction.main_shot = obj["main_shot"]
    if "unit_shot" in obj:
        reconstruction.unit_shot = obj["unit_shot"]

    # Extract reference topocentric frame
    if "reference_lla" in obj:
        lla = obj["reference_lla"]
        reconstruction.reference = geo.TopocentricConverter(
            lla["latitude"], lla["longitude"], lla["altitude"]
        )

    return reconstruction
Exemple #15
0
def reconstruction_from_json(obj):
    """
    Read a reconstruction from a json object
    """
    reconstruction = types.Reconstruction()

    # Extract cameras
    for key, value in iteritems(obj['cameras']):
        camera = camera_from_json(key, value)
        reconstruction.add_camera(camera)

    # Extract shots
    for key, value in iteritems(obj['shots']):
        shot_from_json(reconstruction, key, value)

    # Extract points
    if 'points' in obj:
        for key, value in iteritems(obj['points']):
            point_from_json(reconstruction, key, value)

    # Extract pano_shots
    if 'pano_shots' in obj:
        for key, value in iteritems(obj['pano_shots']):
            is_pano_shot = True
            shot_from_json(reconstruction, key, value, is_pano_shot)

    # Extract main and unit shots
    if 'main_shot' in obj:
        reconstruction.main_shot = obj['main_shot']
    if 'unit_shot' in obj:
        reconstruction.unit_shot = obj['unit_shot']

    # Extract reference topocentric frame
    if 'reference_lla' in obj:
        lla = obj['reference_lla']
        reconstruction.reference = geo.TopocentricConverter(
            lla['latitude'], lla['longitude'], lla['altitude'])

    return reconstruction
Exemple #16
0
def invent_reference_from_gps_and_gcp(
        data: DataSetBase,
        images: Optional[List[str]] = None) -> geo.TopocentricConverter:
    lat, lon, alt = 0.0, 0.0, 0.0
    wlat, wlon, walt = 0.0, 0.0, 0.0
    if images is None:
        images = data.images()
    for image in images:
        d = data.load_exif(image)
        if "gps" in d and "latitude" in d["gps"] and "longitude" in d["gps"]:
            w = 1.0 / max(0.01, d["gps"].get("dop", 15))
            lat += w * d["gps"]["latitude"]
            lon += w * d["gps"]["longitude"]
            wlat += w
            wlon += w
            if "altitude" in d["gps"]:
                alt += w * d["gps"]["altitude"]
                walt += w

    if not wlat and not wlon:
        for gcp in data.load_ground_control_points():
            lat += gcp.lla["latitude"]
            lon += gcp.lla["longitude"]
            wlat += 1
            wlon += 1

            if gcp.has_altitude:
                alt += gcp.lla["altitude"]
                walt += 1

    if wlat:
        lat /= wlat
    if wlon:
        lon /= wlon
    if walt:
        alt /= walt

    return geo.TopocentricConverter(lat, lon, 0)  # Set altitude manually.
Exemple #17
0
def pairs_and_poses():
    np.random.seed(42)
    data = synthetic_examples.synthetic_cube_scene()

    reconstruction = data.get_reconstruction()
    reference = geo.TopocentricConverter(0, 0, 0)
    input_data = synthetic_scene.SyntheticInputData(reconstruction, reference,
                                                    40, 0.0, 0.0, False)
    features, tracks_manager = input_data.features, input_data.tracks_manager

    points_keys = list(reconstruction.points.keys())
    pairs, poses = defaultdict(list), defaultdict(list)
    for im1, im2 in tracks_manager.get_all_pairs_connectivity():
        tuples = tracks_manager.get_all_common_observations(im1, im2)
        f1 = [p.point for k, p, _ in tuples if k in points_keys]
        f2 = [p.point for k, _, p in tuples if k in points_keys]
        pairs[im1, im2].append((f1, f2))
        pose1 = reconstruction.shots[im1].pose
        pose2 = reconstruction.shots[im2].pose
        poses[im1, im2] = pose2.relative_to(pose1)

    camera = list(reconstruction.cameras.values())[0]
    return pairs, poses, camera, features, tracks_manager, reconstruction
Exemple #18
0
def test_eq_geo() -> None:
    assert geo.TopocentricConverter(40, 30,
                                    0) == geo.TopocentricConverter(40, 30, 0)
    assert geo.TopocentricConverter(40, 32, 0) != geo.TopocentricConverter(
        40, 30, 0)
Exemple #19
0
 def load_reference(self):
     """Load reference as a topocentric converter."""
     lla = self.load_reference_lla()
     return geo.TopocentricConverter(
         lla['latitude'], lla['longitude'], lla['altitude'])
def load_reference(file_path):
        """Load reference as a topocentric converter."""
        lla = load_reference_lla(file_path)
        return geo.TopocentricConverter(
            lla['latitude'], lla['longitude'], lla['altitude'])
Exemple #21
0
def test_read_write_ground_control_points():
    text = """
{
  "points": [
    {
      "id": "1",
      "observations": [
        {
          "shot_id": "01.jpg",
          "projection": [0.7153, 0.5787]
        },
        {
          "shot_id": "02.jpg",
          "projection": [0.8085, 0.3831]
        }
      ]
    },
    {
      "id": "2",
      "position": {
        "latitude": 52.519251158,
        "longitude": 13.400502446,
        "altitude": 16.7021233002
      },
      "observations": [
        {
          "shot_id": "01.jpg",
          "projection": [0.2346, 0.4628]
        }
      ]
    }
  ]
}
    """

    def check_points(points):
        assert len(points) == 2
        p1, p2 = points
        if p1.id != "1":
            p1, p2 = p2, p1

        assert p1.coordinates.has_value is False
        assert len(p1.observations) == 2
        assert np.allclose(p2.lla["latitude"], 52.519251158)
        assert np.allclose(p2.lla["longitude"], 13.400502446)
        assert np.allclose(p2.coordinates.value[2], 16.7021233002)
        assert len(p2.observations) == 1

    reference = geo.TopocentricConverter(52.51913, 13.4007, 0)

    # Read json
    fp = StringIO(text)
    points = io.read_ground_control_points(fp, reference)
    check_points(points)

    # Write json and re-read
    fwrite = StringIO()
    io.write_ground_control_points(points, fwrite, reference)
    freread = StringIO(fwrite.getvalue())
    points_reread = io.read_ground_control_points(freread, reference)
    check_points(points_reread)
Exemple #22
0
def generate_exifs(
    reconstruction: types.Reconstruction,
    gps_noise: Union[Dict[str, float], float],
    causal_gps_noise: bool = False,
) -> Dict[str, Any]:
    """Generate fake exif metadata from the reconstruction."""
    speed_ms = 10.0
    previous_pose = None
    previous_time = 0
    exifs = {}
    reference = geo.TopocentricConverter(0, 0, 0)

    def _gps_dop(shot):
        gps_dop = 15
        if isinstance(gps_noise, float):
            gps_dop = gps_noise
        if isinstance(gps_noise, dict):
            gps_dop = gps_noise[shot.camera.id]
        return gps_dop

    per_sequence = defaultdict(list)
    for shot_name in sorted(reconstruction.shots.keys()):
        shot = reconstruction.shots[shot_name]
        exif = {}
        exif["width"] = shot.camera.width
        exif["height"] = shot.camera.height
        exif["camera"] = str(shot.camera.id)
        exif["make"] = str(shot.camera.id)

        exif["skey"] = str(shot.camera.id)
        per_sequence[exif["skey"]].append(shot_name)

        if shot.camera.projection_type in ["perspective", "fisheye"]:
            exif["focal_ratio"] = shot.camera.focal

        pose = shot.pose.get_origin()
        if previous_pose is not None:
            previous_time += np.linalg.norm(pose - previous_pose) * speed_ms
        previous_pose = pose
        exif["capture_time"] = previous_time

        exifs[shot_name] = exif

    for sequence_images in per_sequence.values():
        if causal_gps_noise:
            sequence_gps_dop = _gps_dop(
                reconstruction.shots[sequence_images[0]])
            perturbations_2d = generate_causal_noise(2, sequence_gps_dop,
                                                     len(sequence_images), 2.0)
        for i, shot_name in enumerate(sequence_images):
            shot = reconstruction.shots[shot_name]
            exif = exifs[shot_name]

            pose = shot.pose.get_origin()

            if causal_gps_noise:
                gps_perturbation = [perturbations_2d[j][i]
                                    for j in range(2)] + [0]
            else:
                gps_noise = _gps_dop(shot)
                gps_perturbation = [gps_noise, gps_noise, 0]

            pose = np.array([pose])
            perturb_points(pose, gps_perturbation)
            pose = pose[0]
            _, _, _, comp = rc.shot_lla_and_compass(shot, reference)
            lat, lon, alt = reference.to_lla(*pose)

            exif["gps"] = {}
            exif["gps"]["latitude"] = lat
            exif["gps"]["longitude"] = lon
            exif["gps"]["altitude"] = alt
            exif["gps"]["dop"] = _gps_dop(shot)
            exif["compass"] = {"angle": comp}

    return exifs
Exemple #23
0
 def load_reference(self) -> geo.TopocentricConverter:
     """Load reference as a topocentric converter."""
     lla = self.load_reference_lla()
     return geo.TopocentricConverter(lla["latitude"], lla["longitude"],
                                     lla["altitude"])