Created by Codex.
Collect Cal3Bundler cameras and three-dimensional tracks, and turn them into structure-from-motion (SfM) bundle-adjustment graphs.
Mathematical idea¶
Bundle adjustment estimates cameras and landmarks by minimizing reprojection error,
where is the observation set. SfmData stores exactly the cameras, points, and observations needed to construct this graph. BAL means Bundle Adjustment in the Large, a standard dataset and file format used by these examples.
import gtsam
import numpy as np
from gtsam import symbol_shorthand
C = symbol_shorthand.C
K = symbol_shorthand.K
P = symbol_shorthand.P
S = symbol_shorthand.S
X = symbol_shorthand.XDataset model¶
SfmData is the central BAL/Bundler-style container. Camera indices in each track address cameraList(). Use FromBalFile or FromBundlerFile for existing datasets, or populate the container directly.
generalSfmFactors() returns only measurement factors. sfmFactorGraph() can additionally fix a camera and point to remove the similarity gauge. Passing None for either fixed index disables that constraint.
data = gtsam.SfmData()
calibration = gtsam.Cal3Bundler(500.0, 0.0, 0.0, 0.0, 0.0)
camera = gtsam.PinholeCameraCal3Bundler(gtsam.Pose3(), calibration)
data.addCamera(camera)
track = gtsam.SfmTrack(np.array([0.0, 0.0, 5.0]))
track.addMeasurement(0, np.array([0.0, 0.0]))
data.addTrack(track)
graph = data.sfmFactorGraph()
print("cameras:", data.numberCameras())
print("tracks:", data.numberTracks())
print("graph factors:", graph.size())cameras: 1
tracks: 1
graph factors: 3
Loading and initialization¶
For a BAL file, a typical start is:
data = gtsam.SfmData.FromBalFile(filename)
graph = data.sfmFactorGraph()
initial = gtsam.initialCamerasAndPointsEstimate(data)For the fastest current CPU bundle-adjustment path, use the point-batched C++ construction described in ../sfm.md; SfmData.sfmFactorGraph() creates one projection factor per observation.