Created by Codex.
Constrain two fundamental matrices by transferring corresponding points into a third view.
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.XMathematical idea¶
Two observations predict epipolar lines in their shared target view,
Their homogeneous intersection is . After dehomogenization, the factor returns ; stacking triplets produces a -dimensional residual.
Model¶
For each (p_a, p_b, p_c) triplet, the factor intersects the two epipolar lines transferred from views a and b into their shared view c, then compares the result with observed p_c. The residual dimension is 2N for N triplets; the noise model must have the same dimension.
Python exposes TransferFactorFundamentalMatrix and TransferFactorSimpleFundamentalMatrix. When intrinsics are known, EssentialTransferFactor stores a fixed calibration with the factor. EssentialTransferFactorK instead treats calibration as an optimized variable. The calibration template has concrete Cal3_S2, Cal3f, and Cal3Bundler variants; the example uses the representative Cal3_S2 forms.
edge_ac = gtsam.EdgeKey(0, 2)
edge_bc = gtsam.EdgeKey(1, 2)
triplets = [(np.array([10.0, 15.0]),
np.array([25.0, 12.0]),
np.array([18.0, 14.0]))]
model = gtsam.noiseModel.Isotropic.Sigma(2 * len(triplets), 1.0)
factor = gtsam.TransferFactorFundamentalMatrix(
edge_ac, edge_bc, triplets, model
)
print("factor keys:", factor.keys())
print("residual dimension:", factor.dim())
calibration = gtsam.Cal3_S2(500.0, 500.0, 0.0, 320.0, 240.0)
fixed_calibration = gtsam.EssentialTransferFactorCal3_S2(
edge_ac, edge_bc, triplets, calibration, model
)
variable_calibration = gtsam.EssentialTransferFactorKCal3_S2(
edge_ac, edge_bc, K(0), triplets, model
)
assert fixed_calibration.dim() == variable_calibration.dim() == 2
print("fixed-calibration keys:", fixed_calibration.keys())
print("variable-calibration keys:", variable_calibration.keys())Practical notes¶
Use consistent edge conventions: an
EdgeKey(i,j)identifies the matrix stored for that view pair.Use several well-spread triplets per factor for a useful constraint.
Jacobians are computed numerically, so this factor is typically more expensive than an analytic reprojection factor.