Implement a method to estimate the essential matrix between two camera views using the 8-point algorithm. This task is crucial in image alignment and stitching as it relates corresponding points in two views through the equation p2TEp1=0. The essential matrix E encodes the rotation and translation between views, up to scale, and is a fundamental concept in computer vision.
To estimate E, the process involves several steps:
Normalizing points to improve numerical stability
Building a constraint matrix A from correspondences
Solving Af=0 via Singular Value Decomposition (SVD)
Enforcing the essential-matrix constraint on E: rank 2 with two equal non-zero singular values, i.e. Σ=diag(s,s,0). Rank 2 alone only gives a fundamental matrix.
E=e11e21e31e12e22e32e13e23e33
This technique is widely used in structure from motion and stereo vision applications.
Example
Input
pts1 = [8 or more corresponding points]
pts2 = [corresponding points in second view]
Output
3×3 essential matrix
Reasoning
Inputs:pts1 and pts2 hold N≥8 matches in normalized camera coordinates (row i of each is one 3D point seen from both views), each treated as p=(x,y,1). In the 12-match test the first pair is (0.065785,−0.110576) and (0.452675,−0.089485).
One equation per match: expanding p2TEp1=0 is linear in the nine entries eij, with coefficients x2x1≈0.0298, x2y1≈−0.0501, x2≈0.4527, …, 1. Twelve matches give 12 equations in 9 unknowns. Since scale is free, you want the unit-norm E that brings all twelve closest to zero.
Structure: that best fit is generally not a valid essential matrix; it is replaced by the nearest matrix with singular values (s,s,0).
Output:E≈0.537−4.2673.1611.6380.549−17.484−3.50017.0011
Its singular values are 17.881,17.881,0, and every match gives p2TEp1≈−0.0001, effectively zero next to entries of size 17.
Notice: any nonzero multiple of E is equally correct, so the tests check structure (rank 2, two equal singular values, near-zero residual), not exact entries.
The essential matrixE encodes the relative pose (rotation R and translation t, up to scale) between two calibrated cameras. For a 3D point X seen in two views with normalized image coordinates p1,\mathbf{p}2∈P2, the epipolar constraint is
p2TEp1=0.
Geometrically, this says: the point in image 2 lies on the epipolar line obtained by transferring the point from image 1 via E.
Algebraically, E has special structure: it can be written as
E=[t]×R,
where [t]× is the skew-symmetric matrix of translation t. This implies rank 2 and two equal non-zero singular values. The 8-point algorithm is a linear method: you stack linear constraints from at least 8 point correspondences into a matrix A, solve A\mathbf{f}=0 (where f is the vectorized E), then project the result onto the space of valid essential matrices (rank-2 constraint via SVD). Normalizing points (centering and scaling) is crucial for numerical stability.
Algorithm/Approach
General pattern for essential (or fundamental) matrix estimation with the 8-point algorithm:
Represent the epipolar constraint as a linear equation in the unknown entries of E.
Use multiple point correspondences to build a linear system A\mathbf{f}=0.
Solve for f as the right singular vector corresponding to the smallest singular value of A.
Reshape f to a 3×3 matrix E, then enforce the rank-2 constraint via SVD.
(In practice with RANSAC) repeat on random minimal subsets, score using inliers, and keep the best E.
Step-by-Step Strategy
Assume you are given corresponding normalized image points {(x1,y1)}↔{(x2,y2)} in homogeneous coordinates p1=(x1,y1,1)T, p2=(x2,y2,1)T.
a) Normalize points (Hartley-style normalization)
For each image separately:
Compute centroid (xˉ,yˉ).
Compute average distance d of points to the centroid.
Define scale s=\sqrt{2}/d.
Build normalization transform
T=s000s0−sxˉ−syˉ1.
Transform points: \tilde{\mathbf{p}} = T \mathbf{p} for both views, giving T1,T2.
b) Build matrix A
For each correspondence (\tilde{\mathbf{p}}_1, \tilde{\mathbf{p}}_2) with coordinates (x1,y1,1) and (x2,y2,1), the epipolar constraint expands to:
Stack all N≥8 correspondences into an N×9 matrix A.
c) Solve A\mathbf{f}=0 via SVD
Compute SVD of A: A=UΣVT.
Take f as the last column of V (corresponding to smallest singular value).
Reshape f into a 3×3 matrix E~.
d) Enforce rank-2 constraint on E
Compute SVD of E~: E~=UEΣEVET, with ΣE=\text{diag}(s1,s2,s3).
For an essential matrix, we need rank(E)=2 and two equal non-zero singular values; a simple enforcement is:
Set s3′=0.
Optionally set s1′=s2′=(s1+s2)/2.
Form
E′=UE⋅diag(s1′,s2′,0)⋅VET.
e) Denormalize
Because you estimated E~ on normalized points:
E=T2TE′T1.
You now have the essential matrixE relating original (calibrated) image coordinates.
Common Pitfalls
Skipping normalization: Leads to very poor numerical stability, especially when coordinates are large (pixel units) or unevenly distributed.
Using uncalibrated coordinates: The essential matrix assumes points are in normalized camera coordinates (after multiplying pixel coords by K−1); otherwise you are really estimating the fundamental matrix instead.
Too few or degenerate points:
Need at least 8 non-degenerate correspondences (not all on a plane/line).
Planar scenes or nearly collinear points can produce unstable or incorrect E.
Incorrect SVD usage:
Solving A\mathbf{f}=0: must take the right singular vector corresponding to the smallest singular value.
Enforcing rank-2: must zero exactly one singular value, not more or less.
Scale ambiguity: E is defined up to a non-zero scalar; don’t rely on its absolute scale. Any downstream pose decomposition should assume this.
In RANSAC:
Use a geometric error (e.g., symmetric epipolar distance) to score inliers.
Ensure you re-estimate E using all inliers after RANSAC picks the best model.
Time & Space Complexity
Let N be the number of correspondences.
Building A:
Time: O(N).
Space: O(N) for the N×9 matrix.
SVD of A:
Since width is constant (9), SVD is O(N) time in practice, with small constant factors.
Space: O(N) to store A plus O(1) for 9×9 matrices in the reduced SVD.
SVD of E (3×3):
Time: O(1).
Space: O(1).
Overall, time complexity is linear in the number of correspondences, O(N), and space complexity is O(N), dominated by storing A and the input matches. In RANSAC, you multiply this by the number of iterations, but each iteration still works on constant-sized subsets for the hypothesis step.