Ejemplo n.º 1
0
def _reconstruction_from_rigs_and_assignments(data: DataSetBase):
    assignments = data.load_rig_assignments()
    models = data.load_rig_models()

    if not data.reference_lla_exists():
        data.invent_reference_lla()

    base_rotation = np.zeros(3)

    reconstructions = []
    for rig_id, instances in assignments.items():
        rig_cameras = models[rig_id]["rig_cameras"]

        reconstruction = types.Reconstruction()
        reconstruction.cameras = data.load_camera_models()
        for instance in instances:
            for image, camera_id in instance:
                rig_camera = rig_cameras[camera_id]
                rig_pose = pygeometry.Pose(base_rotation)
                rig_pose.set_origin(
                    orec.get_image_metadata(data, image).gps_position.value)
                rig_camera_pose = pygeometry.Pose(rig_camera["rotation"],
                                                  rig_camera["translation"])

                d = data.load_exif(image)
                shot = reconstruction.create_shot(image, d["camera"])
                shot.pose = rig_camera_pose.compose(rig_pose)
                shot.metadata = orec.get_image_metadata(data, image)

        reconstructions.append(reconstruction)
    return reconstructions
Ejemplo n.º 2
0
def rig_statistics(data: DataSetBase, reconstructions):
    stats = {}
    permutation = np.argsort([-len(r.shots) for r in reconstructions])
    for rig_model_id, rig_model in data.load_rig_models().items():
        stats[rig_model_id] = {
            "initial_values": _rig_model_statistics(rig_model)
        }

    for idx in permutation:
        rec = reconstructions[idx]
        for rig_model in rec.rig_models.values():
            if "optimized_values" in stats[rig_model.id]:
                continue
            stats[rig_model.id]["optimized_values"] = _rig_model_statistics(
                rig_model)

    for rig_model_id in data.load_rig_models():
        if "optimized_values" not in stats[rig_model_id]:
            del stats[rig_model_id]

    return stats
Ejemplo n.º 3
0
def bootstrap_reconstruction(data: DataSetBase, tracks_manager, im1, im2, p1,
                             p2):
    """Start a reconstruction using two shots."""
    logger.info("Starting reconstruction with {} and {}".format(im1, im2))
    report: Dict[str, Any] = {
        "image_pair": (im1, im2),
        "common_tracks": len(p1),
    }

    camera_priors = data.load_camera_models()
    camera1 = camera_priors[data.load_exif(im1)["camera"]]
    camera2 = camera_priors[data.load_exif(im2)["camera"]]

    threshold = data.config["five_point_algo_threshold"]
    min_inliers = data.config["five_point_algo_min_inliers"]
    iterations = data.config["five_point_refine_rec_iterations"]
    R, t, inliers, report[
        "two_view_reconstruction"] = two_view_reconstruction_general(
            p1, p2, camera1, camera2, threshold, iterations)

    logger.info("Two-view reconstruction inliers: {} / {}".format(
        len(inliers), len(p1)))
    if len(inliers) <= 5:
        report["decision"] = "Could not find initial motion"
        logger.info(report["decision"])
        return None, report

    rig_model_priors = data.load_rig_models()
    rig_assignments = data.load_rig_assignments_per_image()

    reconstruction = types.Reconstruction()
    reconstruction.reference = data.load_reference()
    reconstruction.cameras = camera_priors
    reconstruction.rig_models = rig_model_priors

    new_shots = add_shot(data, reconstruction, rig_assignments, im1,
                         pygeometry.Pose())
    new_shots += add_shot(data, reconstruction, rig_assignments, im2,
                          pygeometry.Pose(R, t))

    align_reconstruction(reconstruction, None, data.config)
    triangulate_shot_features(tracks_manager, reconstruction, new_shots,
                              data.config)

    logger.info("Triangulated: {}".format(len(reconstruction.points)))
    report["triangulated_points"] = len(reconstruction.points)
    if len(reconstruction.points) < min_inliers:
        report["decision"] = "Initial motion did not generate enough points"
        logger.info(report["decision"])
        return None, report

    to_adjust = {s for s in new_shots if s != im1}
    bundle_shot_poses(reconstruction, to_adjust, camera_priors,
                      rig_model_priors, data.config)

    retriangulate(tracks_manager, reconstruction, data.config)
    if len(reconstruction.points) < min_inliers:
        report[
            "decision"] = "Re-triangulation after initial motion did not generate enough points"
        logger.info(report["decision"])
        return None, report

    bundle_shot_poses(reconstruction, to_adjust, camera_priors,
                      rig_model_priors, data.config)

    report["decision"] = "Success"
    report["memory_usage"] = current_memory_usage()
    return reconstruction, report
Ejemplo n.º 4
0
def grow_reconstruction(data: DataSetBase, tracks_manager, reconstruction,
                        images, gcp):
    """Incrementally add shots to an initial reconstruction."""
    config = data.config
    report = {"steps": []}

    camera_priors = data.load_camera_models()
    rig_model_priors = data.load_rig_models()

    paint_reconstruction(data, tracks_manager, reconstruction)
    align_reconstruction(reconstruction, gcp, config)

    bundle(reconstruction, camera_priors, rig_model_priors, None, config)
    remove_outliers(reconstruction, config)
    paint_reconstruction(data, tracks_manager, reconstruction)

    should_bundle = ShouldBundle(data, reconstruction)
    should_retriangulate = ShouldRetriangulate(data, reconstruction)
    while True:
        if config["save_partial_reconstructions"]:
            paint_reconstruction(data, tracks_manager, reconstruction)
            data.save_reconstruction(
                [reconstruction],
                "reconstruction.{}.json".format(
                    datetime.datetime.now().isoformat().replace(":", "_")),
            )

        candidates = reconstructed_points_for_images(tracks_manager,
                                                     reconstruction, images)
        if not candidates:
            break

        logger.info("-------------------------------------------------------")
        threshold = data.config["resection_threshold"]
        min_inliers = data.config["resection_min_inliers"]
        for image, _ in candidates:
            ok, new_shots, resrep = resect(
                data,
                tracks_manager,
                reconstruction,
                image,
                threshold,
                min_inliers,
            )
            if not ok:
                continue

            new_shots = set(new_shots)
            images -= new_shots
            bundle_shot_poses(reconstruction, new_shots, camera_priors,
                              rig_model_priors, data.config)

            logger.info(
                f"Adding {' and '.join(new_shots)} to the reconstruction")
            step = {
                "images": list(new_shots),
                "resection": resrep,
                "memory_usage": current_memory_usage(),
            }
            report["steps"].append(step)

            np_before = len(reconstruction.points)
            triangulate_shot_features(tracks_manager, reconstruction,
                                      new_shots, config)
            np_after = len(reconstruction.points)
            step["triangulated_points"] = np_after - np_before

            if should_retriangulate.should():
                logger.info("Re-triangulating")
                align_reconstruction(reconstruction, gcp, config)
                b1rep = bundle(reconstruction, camera_priors, rig_model_priors,
                               None, config)
                rrep = retriangulate(tracks_manager, reconstruction, config)
                b2rep = bundle(reconstruction, camera_priors, rig_model_priors,
                               None, config)
                remove_outliers(reconstruction, config)
                step["bundle"] = b1rep
                step["retriangulation"] = rrep
                step["bundle_after_retriangulation"] = b2rep
                should_retriangulate.done()
                should_bundle.done()
            elif should_bundle.should():
                align_reconstruction(reconstruction, gcp, config)
                brep = bundle(reconstruction, camera_priors, rig_model_priors,
                              None, config)
                remove_outliers(reconstruction, config)
                step["bundle"] = brep
                should_bundle.done()
            elif config["local_bundle_radius"] > 0:
                bundled_points, brep = bundle_local(reconstruction,
                                                    camera_priors,
                                                    rig_model_priors, None,
                                                    image, config)
                remove_outliers(reconstruction, config, bundled_points)
                step["local_bundle"] = brep

            break
        else:
            logger.info("Some images can not be added")
            break

    logger.info("-------------------------------------------------------")

    align_reconstruction(reconstruction, gcp, config)
    bundle(reconstruction, camera_priors, rig_model_priors, gcp, config)
    remove_outliers(reconstruction, config)
    paint_reconstruction(data, tracks_manager, reconstruction)
    return reconstruction, report