Skip to content

Commit 59fd7cd

Browse files
author
Yann N.
committed
Preempt redundant images and resect them at the end
This conservative method greatly speeds-up project with long tracks and highly redundant images. This makes BA faster (smaller fill-in), and experiments shows no regression, even at aggressive thresholds. Nevertheless, we use 0.7 as default, it likely not impact medium overlap dataset like zoo. On ziegeleipark (https://github.com/zivillian/odm_ziegeleipark/tree/master) : 1.0 threshold (no redundancy cull) : 7575 seconds Average Reprojection Error (normalized / pixels / angular)0.24 / 0.65 / 0.00022 Average Track Length 5.50 images Average Track Length (> 2)8.61 images 0.8 threshold : 6843 seconds Average Reprojection Error (normalized / pixels / angular)0.24 / 0.65 / 0.00022 Average Track Length 5.50 images Average Track Length (> 2)8.61 images 0.4 threshold : 4262 seconds Average Reprojection Error (normalized / pixels / angular)0.24 / 0.65 / 0.00023 Average Track Length 5.49 images Average Track Length (> 2)8.60 images
1 parent 75c5f6d commit 59fd7cd

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

opensfm/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ class OpenSfMConfig:
276276
# Maximum optimizer iterations.
277277
bundle_max_iterations: int = 100
278278

279+
# Ratio of (resection candidates / total tracks) of a given image so that it is culled at resection and resected later
280+
resect_redundancy_threshold: float = 0.7
279281
# Retriangulate all points from time to time
280282
retriangulation: bool = True
281283
# Retriangulate when the number of points grows by this ratio

opensfm/reconstruction.py

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,14 +1522,16 @@ def grow_reconstruction(
15221522
should_bundle = ShouldBundle(data, reconstruction)
15231523
should_retriangulate = ShouldRetriangulate(data, reconstruction)
15241524

1525+
local_ba_radius = config["local_bundle_radius"]
1526+
local_ba_grid = config["local_bundle_grid"]
1527+
final_bundle_grid = config["final_bundle_grid"]
1528+
15251529
resection_candidates.add(
15261530
list(reconstruction.shots.keys()),
15271531
list(reconstruction.points.keys()),
15281532
)
1529-
1530-
local_ba_radius = config["local_bundle_radius"]
1531-
local_ba_grid = config["local_bundle_grid"]
1532-
final_bundle_grid = config["final_bundle_grid"]
1533+
redundant_shots = set()
1534+
ratio_redundant = config["resect_redundancy_threshold"]
15331535

15341536
while True:
15351537
if config["save_partial_reconstructions"]:
@@ -1548,7 +1550,17 @@ def grow_reconstruction(
15481550
logger.info("-------------------------------------------------------")
15491551
threshold = data.config["resection_threshold"]
15501552
min_inliers = data.config["resection_min_inliers"]
1551-
for image, _ in candidates:
1553+
1554+
for image, resect_points in candidates:
1555+
1556+
new_tracks = {t for t in tracks_manager.get_shot_observations(image)}
1557+
ratio_existing = resect_points / len(new_tracks) if new_tracks else 1.0
1558+
logger.info("Ratio of resected tracks in {}: {:.2f}".format(image, ratio_existing))
1559+
if ratio_existing > ratio_redundant:
1560+
redundant_shots.add(image)
1561+
images.remove(image)
1562+
continue
1563+
15521564
ok, new_shots, resected_tracks, resrep = resect(
15531565
data,
15541566
tracks_manager,
@@ -1626,8 +1638,14 @@ def grow_reconstruction(
16261638

16271639
break
16281640
else:
1629-
logger.info("Some images can not be added")
1630-
break
1641+
if redundant_shots:
1642+
images.update(redundant_shots)
1643+
redundant_shots.clear()
1644+
ratio_redundant = 1
1645+
local_ba_radius = 0
1646+
else:
1647+
logger.info("Some images can not be added")
1648+
break
16311649

16321650
logger.info("-------------------------------------------------------")
16331651

0 commit comments

Comments
 (0)