Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

TransferFactor

Created by Codex.

Constrain two fundamental matrices by transferring corresponding points into a third view.

Open In Colab

Mathematical idea

Two observations predict epipolar lines in their shared target view,

c(a)=Fcap~a,c(b)=Fcbp~b.\ell_c^{(a)}=F_{ca}\tilde p_a, \qquad \ell_c^{(b)}=F_{cb}\tilde p_b.

Their homogeneous intersection is p^cc(a)×c(b)\hat p_c\propto\ell_c^{(a)}\times\ell_c^{(b)}. After dehomogenization, the factor returns p^cpc\hat p_c-p_c; stacking NN triplets produces a 2N2N-dimensional residual.

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.X

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.

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())
factor keys: [2, 4294967298]
residual dimension: 2

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.