in opensfm/rig.py [0:0]
def create_rigs_with_pattern(data: "DataSet", patterns: TRigPatterns):
"""Create rig data (`rig_cameras.json` and `rig_assignments.json`) by performing
pattern matching to group images belonging to the same instances, followed
by a bit of ad-hoc SfM to find some initial relative poses.
"""
# Construct instances assignments for each rig
instances_per_rig, single_shots = create_instances_with_patterns(
data.images(), patterns
)
for rig_id, instances in instances_per_rig.items():
logger.info(
f"Found {len(instances)} shots for instance {rig_id} using pattern matching."
)
logger.info(f"Found {len(single_shots)} single shots using pattern matching.")
# Create some random subset DataSet with enough images from each rig and run SfM
count = 0
max_rounds = data.config["rig_calibration_max_rounds"]
best_reconstruction = None
best_rig_cameras = None
for subset_data, instances in propose_subset_dataset_from_instances(
data, instances_per_rig, "rig_calibration"
):
if count > max_rounds:
break
count += 1
if len(subset_data.images()) == 0:
continue
# Run a bit of SfM without any rig
logger.info(
f"Running SfM on a subset of {len(subset_data.images())} images. Round {count}/{max_rounds}"
)
actions.extract_metadata.run_dataset(subset_data)
actions.detect_features.run_dataset(subset_data)
actions.match_features.run_dataset(subset_data)
actions.create_tracks.run_dataset(subset_data)
actions.reconstruct.run_dataset(
subset_data, orec.ReconstructionAlgorithm.INCREMENTAL
)
reconstructions = subset_data.load_reconstruction()
if len(reconstructions) == 0:
logger.error("Couldn't run sucessful SfM on the subset of images.")
continue
reconstruction = reconstructions[0]
# Compute some relative poses
rig_cameras = create_rig_cameras_from_reconstruction(
reconstruction, instances_per_rig
)
found_cameras = {c for i in instances_per_rig.values() for _, c in i}
if set(rig_cameras.keys()) != found_cameras:
logger.error(
f"Calibrated {len(rig_cameras)} whereas {len(found_cameras)} were requested. Rig creation failed."
)
continue
reconstructed_instances = count_reconstructed_instances(
instances, reconstruction
)
logger.info(
f"reconstructed {reconstructed_instances} instances over {len(instances)}"
)
if (
reconstructed_instances
< len(instances) * data.config["rig_calibration_completeness"]
):
logger.error(
f"Not enough reconstructed instances: {reconstructed_instances} instances over {len(instances)} instances."
)
continue
best_reconstruction = reconstruction
best_rig_cameras = rig_cameras
break
if best_reconstruction and best_rig_cameras:
logger.info(
f"Found a candidate for rig calibration with {len(best_reconstruction.shots)} shots"
)
data.save_rig_cameras(best_rig_cameras)
data.save_rig_assignments(instances_per_rig)
else:
logger.error(
"Could not run any sucessful SfM on images subset for rig calibration"
)