Transformations, alignment, and Sim3¶
This chapter covers similarity / rigid transforms for point clouds, full reconstructions, and ray–point (gDLS) problems. The C++ code lives under src/theia/sfm/transformation/. Most entry points are on pytheia.sfm (import pytheia as pt → pt.sfm).
For Python layout, see Python API overview.
Similarity convention¶
Point map: a similarity acts on Euclidean 3D points as
Umeyama alignment maps the left set A to the right set B:
(AlignPointCloudsUmeyama(left, right) in Theia follows that naming.)
Whole Reconstruction: TransformReconstruction applies the same \((\mathbf{R}, \mathbf{t}, s)\) to every estimated camera and track: 3D points use the formula above; camera orientations and positions are updated consistently (see transform_reconstruction.cc).
Point cloud alignment (Umeyama)¶
Python (pt.sfm) |
Meaning |
|---|---|
AlignPointCloudsUmeyama(left, right) |
Closed-form least-squares similarity between matched 3D points (Umeyama). Returns (R, t, scale) as numpy arrays / Eigen types. |
AlignPointCloudsUmeyamaWithWeights(left, right, weights) |
Same with a positive weight per correspondence. |
Correspondences must be aligned by index; left[i] matches right[i].
gDLS: generalized pose and scale from rays¶
GdlsSimilarityTransform implements gDLS (Sweeney et al., ECCV 2014): given camera centers ray_origin, unit view directions ray_direction, and world points world_point (same count, ≥ 4), it returns multiple candidate similarities that align rays to points.
Python returns a tuple (quats_wxyz, translations, scales) — per-solution quaternion as length-4 \([w,x,y,z]\), translation Vector3, and scalar scale (see transformation_wrapper.cc).
Use this for loop closure, localization, or other PnP-with-scale settings where a single similarity explains many ray–point pairs.
Aligning two reconstructions¶
Python (pt.sfm) |
Meaning |
|---|---|
AlignReconstructions(fixed_recon, variable_recon) |
Estimates a similarity that best aligns variable_recon to fixed_recon using shared (same view name) estimated cameras; updates variable_recon in place. Returns (R, t, scale). |
AlignReconstructionsRobust(threshold, fixed_recon, variable_recon) |
RANSAC over camera centers, then refit on inliers; threshold is allowed position error for inliers. |
These wrap align_reconstructions.h.
!!! note "C++ only"
[`AlignOverlapReconstructionsWithPointsAndPosesRobust`](https://github.com/urbste/pyTheiaSfM/blob/master/src/theia/sfm/transformation/align_reconstructions.h) and pose-graph–style alignment in [`align_reconstructions_pose_graph_optim.h`](https://github.com/urbste/pyTheiaSfM/blob/master/src/theia/sfm/transformation/align_reconstructions_pose_graph_optim.h) are **not** currently exposed in pybind.
Applying a known similarity to a reconstruction¶
Python (pt.sfm) |
Meaning |
|---|---|
TransformReconstruction(reconstruction, R, t, scale) |
Apply \((\mathbf{R}, \mathbf{t}, s)\) to all estimated views and tracks in place. |
TransformReconstruction4(reconstruction, T4) |
Same using a 4×4 matrix: T4[:3,:3] = \(\mathbf{R}\), T4[:3,3] = \(\mathbf{t}\), T4[3,3] = scale (Theia packs Sim3 this way, not a standard ([R |
Ceres-based Sim3 point cloud alignment¶
OptimizeAlignmentSim3(source_points, target_points, options) aligns two point clouds with Sim(3): unless you pass an initial guess via Sim3AlignmentOptions.set_initial_sim3_params, it initializes with weighted Umeyama and then runs Ceres refinement (point-to-point, robust, or point-to-plane per alignment_type).
Sim3AlignmentType:POINT_TO_POINT,ROBUST_POINT_TO_POINT,POINT_TO_PLANESim3AlignmentOptions: alignment type, Huber / outlier thresholds,max_iterations, per-point weights (set_point_weights), optional target normals for point-to-plane (set_target_normals), optional initial Sim3 (set_initial_sim3_params), Ceres-related fields on the C++ structSim3AlignmentSummary:success,sim3_params(7-vector),alignment_error,num_iterations,final_cost
Parameterization helpers (Sophus::Sim3):
Sim3FromRotationTranslationScale(R, t, scale)→Vector7d(sim3.log())Sim3ToRotationTranslationScale(sim3_params)→(R, t, scale)Sim3ToHomogeneousMatrix(sim3_params)→4×4in the same layout asTransformReconstruction4
Small structs¶
SimilarityTransformation—rotation(3×3),translation(3),scale(float)RigidTransformation—rotation,translation(scale fixed to 1 in semantics elsewhere)
Rotating a set of global orientations to reference¶
To align a list of angle-axis rotations \(\omega_i\) (Ceres convention) to ground-truth rotations of the same length, use pytheia.math.AlignRotations(gt_rotations, rotations): it solves for a global rotation correction and updates rotations in place so that rotations * R ≈ gt_rotations in the aggregate least-squares sense (see rotation.h).
pytheia.math.AlignOrientations is a thin wrapper when data are stored as dict[view_id → angle_axis].
Prefer these math helpers over any duplicate sfm binding for rotation alignment unless you have verified the sfm signature matches your use case.
See also¶
- SfM —
Reconstruction,View,Track - Bundle adjustment — refine after applying a global transform
- Pose — geometry that produces rays for gDLS
- Math —
AlignRotations,AlignOrientations,MultiplyRotations, …