Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/scripts/execute_single_benchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,34 @@ execute_gtsfm() {
esac
fi

if [[ "$config_name" == "sift_global_positioner" ]]; then
log INFO "Running GTSFM with Global Positioner (BATA) pipeline configuration"

case "$loader_name" in
olsson-loader)
./run --num_workers 1 \
--loader olsson \
--dataset_dir "$DATASET_ROOT" \
--config_name sift_global_positioner \
--max_frame_lookahead "$max_frame_lookahead" \
--max_resolution "$max_resolution" \
$share_intrinsics_arg
return $?
;;
colmap-loader)
./run --num_workers 1 \
--loader colmap \
--dataset_dir "$DATASET_DIR" \
--images_dir "$IMAGES_DIR" \
--config_name sift_global_positioner \
--max_frame_lookahead "$max_frame_lookahead" \
--max_resolution "$max_resolution" \
$share_intrinsics_arg
return $?
;;
esac
fi

log INFO "Executing GTSFM with $loader_name..."

case "$loader_name" in
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,26 @@ jobs:
[sift , door-12 , 15, JPG, test_data, olsson-loader , 1296, true ],
[lightglue , door-12 , 15, JPG, test_data, olsson-loader , 1296, true ],
[megaloc , door-12 , 15, JPG, test_data, olsson-loader , 1296, true ],
[sift_global_positioner, door-12 , 15, JPG, test_data, olsson-loader , 1296, true ],
[sift , skydio-8 , 15, jpg, wget , colmap-loader , 760, true ],
[lightglue , skydio-8 , 15, jpg, wget , colmap-loader , 760, true ],
[megaloc , skydio-8 , 15, jpg, wget , colmap-loader , 760, true ],
[sift_global_positioner, skydio-8, 15, jpg, wget , colmap-loader , 760, true ],
[sift , skydio-32 , 15, jpg, wget , colmap-loader , 760, true ],
[lightglue , skydio-32 , 15, jpg, wget , colmap-loader , 760, true ],
[megaloc , skydio-32 , 15, jpg, wget , colmap-loader , 760, true ],
[sift_global_positioner, skydio-32, 15, jpg, wget , colmap-loader , 760, true ],
[sift , palace-fine-arts-281 ,15, jpg, wget , olsson-loader , 320, true ],
[sift_global_positioner, palace-fine-arts-281, 15, jpg, wget, olsson-loader, 320, true ],
[lightglue , notre-dame-20 , 15, jpg, wget , colmap-loader , 760, false],
[sift , 2011205_rc3 , 15, png, wget , astrovision , 1024, true ],
[lightglue , 2011205_rc3 , 15, png, wget , astrovision , 1024, true ],
[sift , gerrard-hall-100 , 15, jpg, wget , colmap-loader , 760, true ],
[lightglue , gerrard-hall-100 , 15, jpg, wget , colmap-loader , 760, true ],
[sift_global_positioner, gerrard-hall-100, 15, jpg, wget, colmap-loader, 760, true ],
[sift , south-building-128 , 15, jpg, wget , colmap-loader , 760, true ],
[lightglue , south-building-128 , 15, jpg, wget , colmap-loader , 760, true ],
[sift_global_positioner, south-building-128, 15, jpg, wget, colmap-loader, 760, true ],
]

steps:
Expand Down
140 changes: 140 additions & 0 deletions gtsfm/configs/sift_global_positioner.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# SIFT front-end with Global Positioner (replaces translation averaging + data association).
#
# Uses the GLOMAP-inspired BATA bearing factor graph to jointly estimate
# camera positions and 3D points, feeding directly into global BA.
#
# Pipeline: rot_avg → GlobalPositioner → BA
# (instead of: rot_avg → trans_avg → data_assoc → BA)
#
# Front-end matches unified.yaml exactly for fair A/B comparison with CI benchmarks.
# Only the multiview_optimizer differs: global_positioner is added.

# @package _global_
_target_: gtsfm.scene_optimizer.SceneOptimizer

loader:
_target_: gtsfm.loader.Olsson

image_pairs_generator:
_target_: gtsfm.retriever.image_pairs_generator.ImagePairsGenerator
global_descriptor:
_target_: gtsfm.frontend.cacher.global_descriptor_cacher.GlobalDescriptorCacher
global_descriptor_obj:
_target_: gtsfm.frontend.global_descriptor.NetVLAD
retriever:
_target_: gtsfm.retriever.JointSimilaritySequential
num_matched: 5
min_score: 0.3
max_frame_lookahead: 15
batch_size: 2

graph_partitioner:
_target_: gtsfm.graph_partitioner.Single

cluster_optimizer:
_target_: gtsfm.cluster_optimizer.Multiview
correspondence_generator:
_target_: gtsfm.frontend.correspondence_generator.det_desc_correspondence_generator.DetDescCorrespondenceGenerator

detector_descriptor:
_target_: gtsfm.frontend.cacher.detector_descriptor_cacher.DetectorDescriptorCacher
detector_descriptor_obj:
_target_: gtsfm.frontend.detector_descriptor.sift.SIFTDetectorDescriptor
max_keypoints: 5000

matcher:
_target_: gtsfm.frontend.cacher.matcher_cacher.MatcherCacher
matcher_obj:
_target_: gtsfm.frontend.matcher.twoway_matcher.TwoWayMatcher
ratio_test_threshold: 0.8

two_view_estimator:
_target_: gtsfm.two_view_estimator_cacher.TwoViewEstimatorCacher
two_view_estimator_obj:
_target_: gtsfm.two_view_estimator.TwoViewEstimator
bundle_adjust_2view: True
eval_threshold_px: 4 # in px
ba_reproj_error_thresholds: [0.5]
bundle_adjust_2view_maxiters: 100

verifier:
_target_: gtsfm.frontend.verifier.ransac.Ransac
use_intrinsics_in_verification: True
estimation_threshold_px: 4 # for H/E/F estimators

triangulation_options:
_target_: gtsfm.data_association.point3d_initializer.TriangulationOptions
mode:
_target_: gtsfm.data_association.point3d_initializer.TriangulationSamplingMode
value: NO_RANSAC

inlier_support_processor:
_target_: gtsfm.two_view_estimator.InlierSupportProcessor
min_num_inliers_est_model: 15
min_inlier_ratio_est_model: 0.1
save_gtsfm_data: True
save_3d_viz: False
save_two_view_viz: False
pose_angular_error_thresh: 5 # degrees
multiview_optimizer:
_target_: gtsfm.multi_view_optimizer.MultiViewOptimizer

# Matches unified.yaml exactly
view_graph_estimator:
_target_: gtsfm.view_graph_estimator.cycle_consistent_rotation_estimator.CycleConsistentRotationViewGraphEstimator
edge_error_aggregation_criterion: MIN_EDGE_ERROR

rot_avg_module:
_target_: gtsfm.averaging.rotation.shonan.ShonanRotationAveraging
weight_by_inliers: True

# trans_avg_module and data_association_module are required for
# backwards compatibility but are unused when global_positioner is set.
trans_avg_module:
_target_: gtsfm.averaging.translation.averaging_1dsfm.TranslationAveraging1DSFM
robust_measurement_noise: True
projection_sampling_method: SAMPLE_INPUT_MEASUREMENTS
reject_outliers: False
use_all_tracks_for_averaging: True
use_relative_camera_poses: True

data_association_module:
_target_: gtsfm.data_association.data_assoc.DataAssociation
min_track_len: 3
triangulation_options:
_target_: gtsfm.data_association.point3d_initializer.TriangulationOptions
reproj_error_threshold: 10
mode:
_target_: gtsfm.data_association.point3d_initializer.TriangulationSamplingMode
value: RANSAC_SAMPLE_UNIFORM
max_num_hypotheses: 100
save_track_patches_viz: False

# Global Positioner: replaces trans_avg + data_assoc with joint optimization.
# Uses GTSAM's native BilinearAngleTranslationFactor (C++) for full speed.
global_positioner:
_target_: gtsfm.global_positioner.global_positioner.GlobalPositioner
noise_sigma: 0.01
huber_loss_scale: 0.1
max_iterations: 30
min_track_measurements: 3
max_reproj_error: 5.0
save_iteration_visualization: True

bundle_adjustment_module:
_target_: gtsfm.bundle.bundle_adjustment.BundleAdjustmentOptimizer
reproj_error_thresholds: [10, 5, 3]
robust_ba_mode: "HUBER"
shared_calib: False
cam_pose3_prior_noise_sigma: 0.1
calibration_prior_focal_sigma: 20.0
measurement_noise_sigma: 1.0

# comment out to not run
dense_multiview_optimizer:
_target_: gtsfm.densify.mvs_patchmatchnet.MVSPatchmatchNet

gaussian_splatting_optimizer:
_target_: gtsfm.splat.gaussian_splatting.GaussianSplatting
cfg:
_target_: gtsfm.splat.gaussian_splatting.Config
1 change: 1 addition & 0 deletions gtsfm/global_positioner/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Global positioner module — joint camera + point estimation using bearing constraints."""
Loading
Loading