Fundamental Matrix Estimation (8-Point Algorithm)
The Fundamental Matrix F defines the geometric relationship between corresponding points in two images from uncalibrated cameras. For corresponding points x1 and x2, they must satisfy the epipolar constraint:
x2T⋅F⋅x1=0
Your task is to implement the 8-Point Algorithm to estimate F from point correspondences:
-
Build matrix A: For each point pair, create a row: [x2x1,x2y1,x2,y2x1,y2y1,y2,x1,y1,1]
-
Solve Af=0: Use SVD to find the vector f that minimizes ∥Af∥2 subject to ∥f∥=1. This is the last column of V (or last row of VT).
-
Reshape: Convert the 9-element vector f into a 3×3 matrix F.
-
Normalize: Divide F by its Frobenius norm ∥F∥F.
Return F as a 3×3 matrix with elements rounded to 4 decimal places.
Example:
x1_pairs = [[10, 50, 1], [20, 60, 1], [30, 70, 1], [40, 80, 1],
[50, 90, 1], [60, 100, 1], [70, 110, 1], [80, 120, 1]]
x2_pairs = [[15, 55, 1], [25, 65, 1], [35, 75, 1], [45, 85, 1],
[55, 95, 1], [65, 105, 1], [75, 115, 1], [85, 125, 1]][[-0.0005, 0.0034, -0.2376], [-0.0046, 0.0018, -0.0783], [0.2271, -0.003, 0.9412]]
- Build 8×9 matrix A from point pairs
- Compute SVD: A=UΣVT
- f = last row of VT (corresponds to smallest singular value)
- Reshape f to 3×3 matrix F
- Normalize: F=F/∥F∥F
Constraints:
- At least 8 corresponding point pairs required
- Input points are in homogeneous coordinates [x,y,1]
- Output F should be normalized (Frobenius norm = 1)
- Round output elements to 4 decimal places
1. Background Knowledge
The Fundamental Matrix F encodes the epipolar geometry between two uncalibrated images, capturing the projective relationship between corresponding points x1=[x1,y1,1]T in image 1 and x2=[x2,y2,1]T in image 2. These points satisfy the epipolar constraint:
x2TFx1=0Key concepts:
- Epipolar geometry: Projects a point from one image onto an epipolar line in the other image, reducing the 2D search to 1D.
- F is a 3×3 matrix with rank 2 (determinant zero) and 7 degrees of freedom (9 elements minus 1 scale, minus 1 rank constraint).
- Homogeneous coordinates: Points are represented as [x,y,1]T, invariant to scaling.
- Uncalibrated cameras: No intrinsic parameters (K1, K2) known; F relates image coordinates directly.
Prerequisites:
- Linear algebra: SVD decomposition, null space computation.
- Geometry: Projective transformations, coplanarity of rays from corresponding points.
2. Algorithm Approach
The 8-Point Algorithm is a linear method to estimate F from ≥8 point correspondences. It solves the homogeneous system:
Af=0where f=\text{vec}(F) is the 9×1 vectorized F, and A has rows from each correspondence:
[x2x1,y2x1,x1,x2y1,y2y1,y1,x2,y2,1]Core technique: SVD
- Compute SVD: A=UΣVT.
- f is the right singular vector corresponding to the smallest singular value (last column of V), ensuring ∥f∥=1 and minimizing ∥Af∥2.
Post-processing:
- Reshape f to 3×3 matrix F.
- Normalize: F←F/∥F∥F (Frobenius norm).
Why 8 points? F has 7 DOF; 8 points provide a unique (up to scale) solution.
3. Step-by-Step Strategy
-
Input validation: Ensure ≥8 point pairs, all in homogeneous form [x,y,1].
-
Construct A∈RN×9:
For each pair (x1,y1), (x2,y2):
A[i] = [x2*x1, y2*x1, x1, x2*y1, y2*y1, y1, x2, y2, 1]
-
SVD decomposition: U,Σ,VT=\text{svd}(A).
-
Extract f: f=V[:,−1] (last column of V).
-
Reshape: F=\text{reshape}(f,3,3).
-
Normalize: F=F/∥\text{Frobenius}(F)∥.
-
Round: Fij←\text{round}(Fij,4).
Pseudocode:
import numpy as np
def eight_point_algorithm(pts1, pts2):
assert len(pts1) >= 8
A = np.zeros((len(pts1), 9))
for i, ((x1,y1), (x2,y2)) in enumerate(zip(pts1, pts2)):
A[i] = [x2*x1, y2*x1, x1, x2*y1, y2*y1, y1, x2, y2, 1]
U, S, Vt = np.linalg.svd(A)
F = Vt[-1].reshape(3,3)
F = F / np.linalg.norm(F, 'fro')
return np.round(F, 4)
4. Common Pitfalls
- Singular A: Fewer than 8 points or degenerate configurations (points coplanar with baseline) → add regularization or check cond(A).
- Scale sensitivity: Inputs must be properly scaled; large coordinates amplify errors → normalize points (e.g., mean=0, std=1) before/after.
- Rank deficiency: Raw SVD F may not have det(F)=0; enforce via SVD(F) and set smallest singular value to 0.
- Numerical precision: Use double precision; round only at end.
- Outliers: Algorithm assumes perfect correspondences; real data needs RANSAC wrapper.
- Frobenius norm: Compute as \sqrt{\sum F_{ij}^2}, not max norm.
5. Time & Space Complexity
- Time: O(N⋅92+93)=O(N+729)=O(N), dominated by SVD of N×9 matrix (fast for N≪104).
- Building A: O(N).
- SVD: O(N⋅92) via standard libraries (e.g., LAPACK).
- Space: O(N⋅9+9⋅9)=O(N).
Scalability: Linear in N; suitable for thousands of points. For refinement, non-linear methods (e.g., LM) add O(N) per iteration but improve accuracy.