Esempio n. 1
0
def add_shots_to_reconstruction(
    shots: List[List[str]],
    positions: List[np.ndarray],
    rotations: List[np.ndarray],
    rig_cameras: List[pymap.RigCamera],
    cameras: List[pygeometry.Camera],
    reconstruction: types.Reconstruction,
    sequence_key: str,
):
    for camera in cameras:
        reconstruction.add_camera(camera)

    rec_rig_cameras = []
    for rig_camera in rig_cameras:
        rec_rig_cameras.append(reconstruction.add_rig_camera(rig_camera))

    for i_shots, position, rotation in zip(shots, positions, rotations):
        instance_id = "_".join([s[0] for s in i_shots])
        rig_instance = reconstruction.add_rig_instance(pymap.RigInstance(instance_id))
        rig_instance.pose = pygeometry.Pose(rotation, -rotation.dot(position))

        for shot, camera in zip(i_shots, cameras):
            shot_id = shot[0]
            rig_camera_id = shot[1]
            shot = reconstruction.create_shot(
                shot_id,
                camera.id,
                pose=None,
                rig_camera_id=rig_camera_id,
                rig_instance_id=instance_id,
            )
            shot.metadata.sequence_key.value = sequence_key
Esempio n. 2
0
def add_shot(data, reconstruction, rig_assignments, shot_id, pose):
    """Add a shot to the recontruction.

    In case of a shot belonging to a rig instance, the pose of
    shot will drive the initial pose setup of the rig instance.
    All necessary shots and rig models will be created.
    """

    added_shots = []
    if shot_id not in rig_assignments:
        camera_id = data.load_exif(shot_id)["camera"]
        shot = reconstruction.create_shot(shot_id, camera_id, pose)
        shot.metadata = get_image_metadata(data, shot_id)
        added_shots = [shot_id]
    else:
        rig_model_id, instance_id, _, instance_shots = rig_assignments[shot_id]

        created_shots = {}
        for shot in instance_shots:
            camera_id = data.load_exif(shot)["camera"]
            created_shots[shot] = reconstruction.create_shot(
                shot, camera_id, pygeometry.Pose())
            created_shots[shot].metadata = get_image_metadata(data, shot)

        rig_instance = reconstruction.add_rig_instance(
            pymap.RigInstance(reconstruction.rig_models[rig_model_id],
                              instance_id))
        for shot in instance_shots:
            _, _, rig_camera_id, _ = rig_assignments[shot]
            rig_instance.add_shot(rig_camera_id, created_shots[shot])
        rig_instance.update_instance_pose_with_shot(shot_id, pose)
        added_shots = instance_shots

    return added_shots
Esempio n. 3
0
    def create_shot(
        self,
        shot_id: str,
        camera_id: str,
        pose: Optional[pygeometry.Pose] = None,
        rig_camera_id: Optional[str] = None,
        rig_instance_id: Optional[str] = None,
    ) -> pymap.Shot:
        passed_rig_camera_id = rig_camera_id if rig_camera_id else camera_id
        passed_rig_instance_id = rig_instance_id if rig_instance_id else shot_id

        if (not rig_camera_id) and (camera_id not in self.rig_cameras):
            self.add_rig_camera(pymap.RigCamera(pygeometry.Pose(), camera_id))
        if passed_rig_camera_id not in self.rig_cameras:
            raise RuntimeError(
                f"Rig Camera {passed_rig_camera_id} doesn't exist in reconstruction"
            )

        if (not rig_instance_id) and (shot_id not in self.rig_instances):
            self.add_rig_instance(pymap.RigInstance(shot_id))
        if passed_rig_instance_id not in self.rig_instances:
            raise RuntimeError(
                f"Rig Instance {passed_rig_instance_id} doesn't exist in reconstruction"
            )

        if pose is None:
            created_shot = self.map.create_shot(shot_id, camera_id,
                                                passed_rig_camera_id,
                                                passed_rig_instance_id)
        else:
            created_shot = self.map.create_shot(shot_id, camera_id,
                                                passed_rig_camera_id,
                                                passed_rig_instance_id, pose)

        return created_shot
Esempio n. 4
0
def _create_rig_instance():
    rec = _create_reconstruction(1, {"0": 2})
    rig_model = rec.add_rig_model(_create_rig_model())
    rig_instance = pymap.RigInstance(rig_model, 1)
    shot = pymap.Shot("0", pygeometry.Camera.create_spherical(), pygeometry.Pose())
    rig_instance.add_shot("rig_camera", shot)
    return rec, rig_instance, shot
Esempio n. 5
0
def _reconstruction_from_rigs_and_assignments(data: DataSetBase):
    assignments = data.load_rig_assignments()
    rig_cameras = data.load_rig_cameras()

    data.init_reference()

    reconstruction = types.Reconstruction()
    reconstruction.cameras = data.load_camera_models()
    for rig_instance_id, instance in assignments.items():
        for image, rig_camera_id in instance:
            rig_camera = rig_cameras[rig_camera_id]
            reconstruction.add_rig_camera(
                pymap.RigCamera(rig_camera.pose, rig_camera_id))

            instance_obj = reconstruction.add_rig_instance(
                pymap.RigInstance(rig_instance_id))
            instance_obj.pose.set_origin(
                helpers.get_image_metadata(data, image).gps_position.value)

            d = data.load_exif(image)
            shot = reconstruction.create_shot(
                image,
                camera_id=d["camera"],
                rig_camera_id=rig_camera_id,
                rig_instance_id=rig_instance_id,
            )
            shot.metadata = helpers.get_image_metadata(data, image)
    return [reconstruction]
Esempio n. 6
0
def test_rig_instance():
    rig_model = _create_rig_model()

    rig_instance = pymap.RigInstance(rig_model)
    shot = pymap.Shot("0", pygeometry.Camera.create_spherical(),
                      pygeometry.Pose())
    rig_instance.add_shot("rig_camera", shot)

    assert list(rig_instance.keys()) == ["0"]
def add_rigs_to_reconstruction(shots, positions, rotations, model,
                               reconstruction):
    rig_model = reconstruction.add_rig_model(model)
    for i, (i_shots, position,
            rotation) in enumerate(zip(shots, positions, rotations)):
        rig_instance = reconstruction.add_rig_instance(
            pymap.RigInstance(rig_model, i))
        for s in i_shots:
            rig_instance.add_shot(s[1], reconstruction.get_shot(s[0]))
        rig_instance.pose = pygeometry.Pose(rotation, -rotation.dot(position))
Esempio n. 8
0
def rig_instance_from_json(
    reconstruction: types.Reconstruction, instance_id: str, obj: Dict[str, Any]
) -> None:
    """
    Read any rig instance from a json shot object
    """
    reconstruction.add_rig_instance(pymap.RigInstance(instance_id))

    pose = pygeometry.Pose()
    pose.rotation = obj["rotation"]
    pose.translation = obj["translation"]
    reconstruction.rig_instances[instance_id].pose = pose
Esempio n. 9
0
def test_rig_instance_create():
    rec = _create_reconstruction(1, {"0": 2})

    rig_model = _create_rig_model()
    rig_instance = pymap.RigInstance(rig_model)
    shot = pymap.Shot("0", pygeometry.Camera.create_spherical(),
                      pygeometry.Pose())
    rig_instance.add_shot("rig_camera", shot)

    rec.add_rig_instance(rig_instance)
    assert len(rec.rig_instances) == 1
    assert list(rec.rig_models.keys()) == ["rig_model"]
    assert list(rec.rig_instances[0].shots.keys()) == ["0"]
Esempio n. 10
0
def perspective_views_of_a_panorama(
    spherical_shot: pymap.Shot,
    width: int,
    reconstruction: types.Reconstruction,
    image_format: str,
    rig_instance_count: Iterator[int],
) -> List[pymap.Shot]:
    """Create 6 perspective views of a panorama."""
    camera = pygeometry.Camera.create_perspective(0.5, 0.0, 0.0)
    camera.id = "perspective_panorama_camera"
    camera.width = width
    camera.height = width
    reconstruction.add_camera(camera)

    names = ["front", "left", "back", "right", "top", "bottom"]
    rotations = [
        tf.rotation_matrix(-0 * np.pi / 2, np.array([0, 1, 0])),
        tf.rotation_matrix(-1 * np.pi / 2, np.array([0, 1, 0])),
        tf.rotation_matrix(-2 * np.pi / 2, np.array([0, 1, 0])),
        tf.rotation_matrix(-3 * np.pi / 2, np.array([0, 1, 0])),
        tf.rotation_matrix(-np.pi / 2, np.array([1, 0, 0])),
        tf.rotation_matrix(+np.pi / 2, np.array([1, 0, 0])),
    ]

    rig_instance = reconstruction.add_rig_instance(
        pymap.RigInstance(str(next(rig_instance_count)))
    )

    shots = []
    for name, rotation in zip(names, rotations):
        if name not in reconstruction.rig_cameras:
            rig_camera_pose = pygeometry.Pose()
            rig_camera_pose.set_rotation_matrix(rotation[:3, :3])
            rig_camera = pymap.RigCamera(rig_camera_pose, name)
            reconstruction.add_rig_camera(rig_camera)
        rig_camera = reconstruction.rig_cameras[name]

        shot_id = add_image_format_extension(
            f"{spherical_shot.id}_perspective_view_{name}", image_format
        )
        shot = reconstruction.create_shot(
            shot_id, camera.id, pygeometry.Pose(), rig_camera.id, rig_instance.id
        )
        shot.metadata = spherical_shot.metadata
        shots.append(shot)
    rig_instance.pose = spherical_shot.pose

    return shots
Esempio n. 11
0
def rig_instance_from_json(reconstruction, key, obj):
    """
    Read any rig instance from a json shot object
    """
    instance_id = int(key)
    reconstruction.add_rig_instance(pymap.RigInstance(instance_id))

    pose = pygeometry.Pose()
    pose.rotation = obj["rotation"]
    pose.translation = obj["translation"]
    reconstruction.rig_instances[instance_id].pose = pose

    for shot_id, rig_camera_id in obj["rig_camera_ids"].items():
        reconstruction.rig_instances[instance_id].add_shot(
            reconstruction.rig_cameras[rig_camera_id],
            reconstruction.shots[shot_id])
Esempio n. 12
0
def add_rigs_to_reconstruction(shots, positions, rotations, rig_cameras,
                               reconstruction):
    rec_rig_cameras = []
    for rig_camera in rig_cameras:
        if rig_camera.id not in reconstruction.rig_cameras:
            rec_rig_cameras.append(reconstruction.add_rig_camera(rig_camera))
        else:
            rec_rig_cameras.append(reconstruction.rig_cameras[rig_camera.id])

    for i, (i_shots, position,
            rotation) in enumerate(zip(shots, positions, rotations)):
        rig_instance = reconstruction.add_rig_instance(pymap.RigInstance(i))
        for j, s in enumerate(i_shots):
            rig_instance.add_shot(rec_rig_cameras[j],
                                  reconstruction.get_shot(s[0]))
        rig_instance.pose = pygeometry.Pose(rotation, -rotation.dot(position))
Esempio n. 13
0
    def create_pano_shot(self,
                         shot_id: str,
                         camera_id: str,
                         pose: Optional[pygeometry.Pose] = None) -> pymap.Shot:
        if pose is None:
            pose = pygeometry.Pose()

        rig_camera_id = f"{PANOSHOT_RIG_PREFIX}{camera_id}"
        if rig_camera_id not in self.rig_cameras:
            self.add_rig_camera(
                pymap.RigCamera(pygeometry.Pose(), rig_camera_id))
        rig_instance_id = f"{PANOSHOT_RIG_PREFIX}{shot_id}"
        if rig_instance_id not in self.rig_instances:
            self.add_rig_instance(pymap.RigInstance(rig_instance_id))

        created_shot = self.map.create_pano_shot(shot_id, camera_id,
                                                 rig_camera_id,
                                                 rig_instance_id, pose)

        return created_shot
Esempio n. 14
0
def add_shot(
    data: DataSetBase,
    reconstruction: types.Reconstruction,
    rig_assignments: Dict[str, Tuple[int, str, List[str]]],
    shot_id: str,
    pose: pygeometry.Pose,
) -> Set[str]:
    """Add a shot to the recontruction.

    In case of a shot belonging to a rig instance, the pose of
    shot will drive the initial pose setup of the rig instance.
    All necessary shots and rig models will be created.
    """

    added_shots = set()
    if shot_id not in rig_assignments:
        camera_id = data.load_exif(shot_id)["camera"]
        shot = reconstruction.create_shot(shot_id, camera_id, pose)
        shot.metadata = get_image_metadata(data, shot_id)
        added_shots = {shot_id}
    else:
        instance_id, _, instance_shots = rig_assignments[shot_id]

        created_shots = {}
        for shot in instance_shots:
            camera_id = data.load_exif(shot)["camera"]
            created_shots[shot] = reconstruction.create_shot(
                shot, camera_id, pygeometry.Pose()
            )
            created_shots[shot].metadata = get_image_metadata(data, shot)

        rig_instance = reconstruction.add_rig_instance(pymap.RigInstance(instance_id))
        for shot in instance_shots:
            _, rig_camera_id, _ = rig_assignments[shot]
            rig_instance.add_shot(
                reconstruction.rig_cameras[rig_camera_id], created_shots[shot]
            )
        rig_instance.update_instance_pose_with_shot(shot_id, pose)
        added_shots = set(instance_shots)

    return added_shots
Esempio n. 15
0
def perspective_views_of_a_panorama(spherical_shot, width, reconstruction,
                                    image_format, rig_instance_count):
    """Create 6 perspective views of a panorama."""
    camera = pygeometry.Camera.create_perspective(0.5, 0.0, 0.0)
    camera.id = "perspective_panorama_camera"
    camera.width = width
    camera.height = width
    reconstruction.add_camera(camera)

    names = ["front", "left", "back", "right", "top", "bottom"]
    rotations = [
        tf.rotation_matrix(-0 * np.pi / 2, (0, 1, 0)),
        tf.rotation_matrix(-1 * np.pi / 2, (0, 1, 0)),
        tf.rotation_matrix(-2 * np.pi / 2, (0, 1, 0)),
        tf.rotation_matrix(-3 * np.pi / 2, (0, 1, 0)),
        tf.rotation_matrix(-np.pi / 2, (1, 0, 0)),
        tf.rotation_matrix(+np.pi / 2, (1, 0, 0)),
    ]

    rig_instance = pymap.RigInstance(next(rig_instance_count))
    rig_instance.pose = spherical_shot.pose

    shots = []
    for name, rotation in zip(names, rotations):
        if name not in reconstruction.rig_cameras:
            rig_camera_pose = pygeometry.Pose()
            rig_camera_pose.set_rotation_matrix(rotation[:3, :3])
            rig_camera = pymap.RigCamera(rig_camera_pose, name)
            reconstruction.add_rig_camera(rig_camera)
        rig_camera = reconstruction.rig_cameras[name]

        shot_id = add_image_format_extension(
            f"{spherical_shot.id}_perspective_view_{name}", image_format)
        shot = reconstruction.create_shot(shot_id, camera.id)
        rig_instance.add_shot(rig_camera, shot)

        shots.append(shot)
    reconstruction.add_rig_instance(rig_instance)

    return shots
Esempio n. 16
0
def reconstruction_from_metadata(data: DataSetBase, images: Iterable[str]) -> types.Reconstruction:
    """Initialize a reconstruction by using EXIF data for constructing shot poses and cameras."""
    data.init_reference()
    rig_assignments = rig.rig_assignments_per_image(data.load_rig_assignments())

    reconstruction = types.Reconstruction()
    reconstruction.reference = data.load_reference()
    reconstruction.cameras = data.load_camera_models()
    for image in images:
        camera_id = data.load_exif(image)["camera"]

        if image in rig_assignments:
            rig_instance_id, rig_camera_id, _ = rig_assignments[image]
        else:
            rig_instance_id = image
            rig_camera_id = camera_id

        reconstruction.add_rig_camera(pymap.RigCamera(pygeometry.Pose(), rig_camera_id))
        reconstruction.add_rig_instance(pymap.RigInstance(rig_instance_id))
        shot = reconstruction.create_shot(
            shot_id=image,
            camera_id=camera_id,
            rig_camera_id=rig_camera_id,
            rig_instance_id=rig_instance_id,
        )

        shot.metadata = get_image_metadata(data, image)

        if not shot.metadata.gps_position.has_value:
            reconstruction.remove_shot(image)
            continue
        gps_pos = shot.metadata.gps_position.value

        shot.pose.set_rotation_matrix(rotation_from_shot_metadata(shot))
        shot.pose.set_origin(gps_pos)
        shot.scale = 1.0
    return reconstruction