Notes / Computer Vision / Note 5 of 6

Leer en español

Epipolar geometry

Where a point seen in one image can appear in a second one, the fundamental matrix that says it, and how to estimate it, with interactive figures.

m2TFm1 = 0

Two pixels can be images of the same point of space only if they pass this test.

F = [BC1]×BA+

The fundamental matrix comes from the two cameras, or from eight pairs of matching points.

Throughout this page, points are drawn in red ink and lines in blue ink. It uses the point on a line and the line through two points from the note on homogeneous coordinates, the camera model from the note on 3D transformations, and the projection matrix and its optical center from the note on camera calibration.

1Two images of one point

One image cannot tell how far away a point is. A pixel m1 fixes the ray on which its point of space lies, the ray from the optical center C1 through m1, but not where on that ray. Now take a second image from another place. A point M of space appears in both, as m1 in the first and m2 in the second. Two such pixels are called corresponding points: images of the same point of space.

Given m1 alone, where can m2 be? M is somewhere on the ray of m1, and every point of that ray is a candidate. The second camera sees each candidate from its own optical center C2. A camera takes a straight line of space to a straight line of the image, so the images of all the candidates lie on one line of the second image. That line is the epipolar line of m1, ℓ2.

This is the epipolar constraint: if m1 and m2 are corresponding points, then m2 lies on the epipolar line of m1. The constraint is necessary, but not sufficient. Every pixel of the line passes it, and only one of them is the image of M. A third image can single it out, as the note on multiple views shows. Still, it turns a search for m2 over the whole second image into a search along one line. In an image of N × N pixels, that is N candidates instead of N2.

2The epipolar plane and the epipoles

The two optical centers and M lie on one plane, the epipolar plane π. Both rays lie on it: the ray of m1 joins C1 and M, and the ray of m2 joins C2 and M. Each image plane cuts π along a line, and those two lines are the epipolar lines. With R1 and R2 for the two image planes,

ℓ1 = π ∩ R1,  ℓ2 = π ∩ R2

So the constraint works both ways. m1 lies on ℓ1, the epipolar line of m2 in the first image.

The line through the two optical centers is the baseline. Another point M′ of space has an epipolar plane π′ of its own, with other epipolar lines. But every epipolar plane contains C1 and C2, so every one contains the baseline. So all the epipolar lines of an image pass through one point, where the baseline crosses its image plane. That point is the image's epipole:

e1 = ⟨C1, C2⟩ ∩ R1,  e2 = ⟨C1, C2⟩ ∩ R2

The baseline passes through both centers, so e1 is where the first camera sees C2, and e2 is where the second camera sees C1.

The example

The example on this page is a series of X-ray images, 2688 × 2208 pixels each, of an object that turns 2° about a vertical axis between one image and the next. The X-ray source plays the part of the optical center, as in the note on 3D transformations. Seen from the object, the source moves around a horizontal circle. Images 1 and 82 are 162° apart on that circle, so their sources almost face each other. Two things follow.

  • The plane of the circle contains both optical centers, so it is an epipolar plane. Both epipoles lie on the line where it crosses the images, which is almost a row of pixels, at v ≈ 1285.
  • Each source lies almost straight ahead of the other, so each image sees the other source, near its edge: both epipoles fall inside their images.

3The fundamental matrix from the two cameras

Now in equations. Call the general projection matrices of the two cameras A and B, as in the note on camera calibration. A point M = [X Y Z 1]T, in the same coordinates for both cameras, appears at

λ1m1 = AM,  λ2m2 = BM

The goal is the epipolar line ℓ2 from m1, A and B alone.

Two points of the ray

ℓ2 is the image of the ray of m1, and a line is fixed by two of its points, so two points of the ray are enough. One is C1. Every ray of the first camera starts there, so A sends it to the zero vector, AC1 = 0, and it can be found from A alone, as in the note on camera calibration.

The other point comes from m1. Any M with AM = m1 projects onto m1, so it lies on the ray. Three equations do not fix four unknowns, but the pseudo-inverse of A picks one solution:

M+ = A+m1,  A+ = AT(AAT)−1

AAT is a 3 × 3 matrix, invertible because A has rank 3. Then AA+ = AAT(AAT)−1 = I, so AM+ = m1. The product the other way round, ATA, would not do: it is 4 × 4 but still has rank 3, so it has no inverse.

M+ is a different point from C1, since A sends it to m1, not to 0. Of all the points of the ray, it is the one whose vector [X Y Z W]T is shortest, which makes it perpendicular to C1 as a vector of four numbers. That choice is a matter of algebra: any other point of the ray would give the same line.

Their images in the second view

B projects both points into the second image:

e2 = BC1,  m2+ = BM+

The first is the epipole, the image of C1. The second is some point of ℓ2.

The line through them

The line through two points is their cross product, as in the note on homogeneous coordinates:

ℓ2 = e2 × m2+ = BC1 × BA+m1

A cross product with a fixed vector u is linear in the other factor, so it is a matrix product, u × v = [u]×v, with

[u]× = 0−u3u2u30−u1−u2u10

Multiplying it by v = [v1 v2 v3]T gives the three components of u × v; the first is u2v3 − u3v2. With u = BC1, the line becomes a matrix times m1:

ℓ2 = Fm1,  F = [BC1]×BA+

The 3 × 3 matrix F is the fundamental matrix. It depends only on A and B, not on m1, m2 or M: one matrix gives the epipolar line of every pixel of the first image.

The epipolar constraint

A point lies on a line when their dot product is zero, ℓTm = 0, as in the note on homogeneous coordinates. So m2 lies on ℓ2 = Fm1 exactly when

m2TFm1 = 0

That is the epipolar constraint as one equation, which every pair of corresponding points satisfies.

Second image:

Drag m1 in image 1, and ℓ2 turns about e2. Slide M along its ray in the lower view, and m2 slides along ℓ2. Drag m2 off the line, and the two rays no longer meet. Change the second image to move C2 around the circle, and drag the background of the lower view to turn it. Each image is drawn in front of its source, where the camera model puts it. With a keyboard, select a point, the lower view or the field with Tab and use the arrow keys.

4Properties of F

Epipolar lines in the first image

Transposing the constraint gives m1TFTm2 = 0, which says that m1 lies on the line FTm2. So

ℓ2 = Fm1,  ℓ1 = FTm2

F takes points of the first image to lines of the second, and FT goes the other way. Swapping the cameras, with B as the first and A as the second, gives FT, up to scale.

Scale

For any number k ≠ 0, kF gives the same lines and the same constraint. So F is homogeneous, like A and B.

Its determinant is 0

[u]×u = u × u = 0, so [u]× sends a vector other than 0 to 0, and it is singular. F has it as a factor, so det F = det [BC1]× · det BA+ = 0. A homogeneous 3 × 3 matrix has eight free numbers, and det F = 0 takes one more away: F has seven degrees of freedom.

The epipoles

Every epipolar line of the second image passes through e2, so e2TFm1 = 0 for every m1. That can only happen if e2TF is the zero row, and in the same way for the other epipole:

Fe1 = 0,  FTe2 = 0

Fe1 = 0 has a picture too. The ray of e1 is the baseline itself, which passes through C2, so the second camera sees the whole ray as one point, e2, not as a line. And the zero vector stands for no line.

These equations find the epipoles from F alone. FTe2 = 0 says that e2 is perpendicular to every column of F, so it is the cross product of two columns of F, divided by its third component to read it. In the same way, e1 is the cross product of two rows of F.

Two images from one optical center

If C2 = C1, then BC1 = 0 and F = 0: there is no baseline, no epipole and no epipolar line. Both images then show the same rays, and they are related by a homography instead, as in the note on 2D transformations.

5The same F from one determinant

The same F comes out of the two projection equations without drawing any line. Move all their terms to the left, AM − λ1m1 = 0 and BM − λ2m2 = 0. That is six equations in six unknowns, the four components of M, λ1 and λ2, and they form one system Gv = 0:

Am10B0m2M−λ1−λ2 = 0

Here G is 6 × 6: A and B fill its first four columns, m1 and m2 its last two. If m1 and m2 correspond, the point M they come from gives a solution v ≠ 0. A square system with right side 0 has a solution other than 0 only when its determinant is 0, so det G = 0.

Expand det G along its last two columns, the only ones that hold the pixels. Picking component j of m1 strikes out row j of A, and picking component i of m2 strikes out row i of B. Each term is those two components times the 4 × 4 determinant of the rows left: two rows of A and two of B. So det G is linear in m1 and linear in m2, which is exactly the form m2TFm1, with

Fij = (−1)i+j det A without row jB without row i

For the two images of the example, this F equals [BC1]×BA+ up to scale, to eleven significant digits. It also shows why the constraint has this form and no other: det G is linear in each pixel, however the cameras are placed.

6Measured points miss the line

Real pixels are measured and A and B are estimated, so a pair of corresponding points almost never satisfies m2TFm1 = 0 exactly: m2 lies near its epipolar line, not on it. So the constraint is used with a tolerance. m2 is accepted as a possible match when its distance to ℓ2 = Fm1 = [a b c]T is below some d0:

d = |m2TFm1|√(a2 + b2) < d0

Why this is the distance: (a, b) is perpendicular to the line ax + by + c = 0. Moving a point by a distance t along the unit vector (a, b)/√(a2 + b2) changes ax + by + c by t√(a2 + b2), and the value is 0 on the line. So the value at m2, which is m2TFm1, divided by √(a2 + b2), is how far m2 is from the line. A line scaled so that a2 + b2 = 1 gives the distance directly, with a sign for the side.

The tolerance depends on how well the pixels and the cameras are known: a pixel or two for corners found by a program, more for points clicked by hand. With a third image the test becomes much stricter, as the note on multiple views shows.

7Estimating F from corresponding points

So far F came from A and B. When the cameras are not calibrated, F can be estimated from the images alone, from pairs of points known to correspond, such as the same corner found in both. Each pair m1 = [x1 y1 1]T, m2 = [x2 y2 1]T satisfies m2TFm1 = 0. Multiplied out,

(F11x1 + F12y1 + F13)x2 + (F21x1 + F22y1 + F23)y2 + F31x1 + F32y1 + F33 = 0

Fij multiplies component i of m2 and component j of m1, and the pixels are known numbers, so the equation is linear in the nine entries of F. Stacking them row by row in f = [F11 F12 … F33]T, each pair gives one row:

[x1x2 y1x2 x2 x1y2 y1y2 y2 x1 y1 1] f = 0

Eight pairs

F is homogeneous, so one entry can be fixed, as a34 was in calibration: F33 = 1. The last term of each row moves to the right side, and the eight unknowns left, f′ = [F11 … F32]T, satisfy

Qf′ = r

where each row of Q is [x1x2 y1x2 x2 x1y2 y1y2 y2 x1 y1] and each entry of r is −1. Eight pairs give a square system, solved as f′ = Q−1r. More pairs are fitted by least squares, as in calibration: f′ = (QTQ)−1QTr.

Fixing F33 = 1 fails only if the true F33 is 0. F33 is m2TFm1 for m1 = m2 = [0 0 1]T, so that happens when pixel (0, 0) of the second image lies on the epipolar line of pixel (0, 0) of the first. The choice can also be avoided, as for homographies and calibration: keep all nine unknowns and solve Qf = 0 with ‖f‖ = 1, whose answer is the right singular vector of Q with the smallest singular value.

Why eight, when F has seven degrees of freedom

The linear method treats the eight ratios of F as independent. It cannot also impose det F = 0, which is not a linear condition on the entries of F, so it needs eight equations. And an estimate from measured pixels is not exactly singular.

Which pairs

Eight pairs are not enough if their points of space all lie on one plane. The pixels of a plane in two images are related by a homography, as in the note on 2D transformations, and then Q has rank 6 at most: a whole family of matrices satisfies every equation. The points must spread in depth, off any single plane.

How sensitive it is

In pixels, the columns of Q differ enormously in size: x1x2 reaches 7·106 in images of this size, while x1 stays below 3000. The entries of F differ in the opposite way, and small errors in the pixels are magnified. With exactly eight pairs, the estimate passes each epipolar line exactly through its m2, a wrong one included, and the lines of all the other points pay for it. More pairs, fitted by least squares, let the fit notice the wrong one: its line no longer follows it, and the others move less.

In the figure below, the pairs are points of the object, projected into images 1 and 82 and rounded to whole pixels. The rounding alone leaves the lines of other points of the object 1.10 pixels from their true matches on average with eight pairs, and 0.47 with sixteen. Moving the point of pair 3 in image 82 down by 30 pixels makes the difference plain. With eight pairs, its line follows it exactly, and the lines of the other points move off by 22.38 pixels on average. With sixteen, its line stays 21.12 pixels from it, and the others move off by only 2.90.

Select a pair by clicking its point in image 82, then drag that point in the close-up, up to 30 pixels, as if it had been clicked in the wrong place. The blue lines are the epipolar lines that the estimated F gives in image 82 for the points of image 1. The dashed line is the true one for the selected pair, from the two cameras. In the close-up, the grid lines are 10 pixels apart. With a keyboard, select a pair's point with Tab and press Enter, then select the point in the close-up and use the arrow keys; it moves one pixel per press.

8Summary

The key ideas next to their NumPy equivalents. In code, A, B and F are mat_a, mat_b and mat_f, and pixels are homogeneous vectors such as m1 = np.array([x1, y1, 1]).

Optical center
AC1 = 0
c1 = np.linalg.svd(mat_a)[2][-1]
Pseudo-inverse
A+ = AT(AAT)−1, AA+ = I
np.linalg.pinv(mat_a)
Cross product as a matrix
[u]×v = u × v
def skew(u):
    return np.array([
        [0, -u[2], u[1]],
        [u[2], 0, -u[0]],
        [-u[1], u[0], 0]])
Fundamental matrix
F = [BC1]×BA+
mat_f = skew(mat_b @ c1) @ mat_b \
    @ np.linalg.pinv(mat_a)
Epipolar lines
ℓ2 = Fm1, ℓ1 = FTm2
ell_2 = mat_f @ m1
ell_1 = mat_f.T @ m2
Is it a match?
|m2TFm1| / √(a2 + b2) < d0
d = abs(m2 @ ell_2) / np.hypot(
    ell_2[0], ell_2[1])
Epipoles
Fe1 = 0, FTe2 = 0
e2 = np.cross(mat_f[:, 0],
    mat_f[:, 1])
e2 = e2 / e2[2]
Eight or more pairs, F33 = 1
Qf′ = r, f′ = (QTQ)−1QTr
Q = np.column_stack([
    x1*x2, y1*x2, x2, x1*y2,
    y1*y2, y2, x1, y1])
f = np.linalg.lstsq(
    Q, -np.ones(len(Q)),
    rcond=None)[0]
mat_f = np.append(f, 1)
mat_f = mat_f.reshape(3, 3)