Skip to content
AI360Xpert
Beta

Homography: Mapping Planes Across Views

A homography is a 3 by 3 matrix mapping one plane to another: the same wall seen from two angles, or a tilted document photographed and flattened. It holds only while everything mapped stays flat.

One 3 by 3 H maps every point of a plane: translation by (2,1) sends (3,4) to (5,5)
One 3 by 3 H maps every point of a plane: translation by (2,1) sends (3,4) to (5,5)

Why Does This Exist?

Walls, roads, documents, and sports fields are planes, and planes map to planes with a simple linear rule where general scenes need the heavier fundamental matrix. Whenever the world cooperates by staying flat, one 3×33 \times 3 matrix aligns the views, flattens the document, or stitches the panorama. This page covers when that deal holds, what HH contains, and how to read a decomposition. The fitting machinery, DLT inside RANSAC, lives in homography estimation and is not repeated here.

Think of It Like This

A slide projector sheet

Tilt a projector sheet and its rectangle keystones into a trapezoid; the keystone recipe that restores it is fixed by the tilt. That recipe is HH: four corner pins determine the whole warp, and every interior point follows.

The analogy stops at crumpling: tilt the sheet and one recipe still fits, but crumple it and no single matrix works. Flatness is the whole contract, and parallax is the crumple.

How It Actually Works

A homography maps homogeneous points up to scale: x′∼Hxx' \sim H x, with HH a 3×33 \times 3 matrix carrying 88 degrees of freedom (nine entries minus global scale). It applies exactly when the mapped points share a plane, or when the camera purely rotates (H=KRK−1H = K R K^{-1}, which is why panoramas stitch without any plane at all). For a plane with normal nn at distance dd, the plane-induced form is H=R+tnT/dH = R + t n^T / d, with RR and tt the relative motion. Decomposing HH recovers that motion plus the plane, up to a twofold ambiguity resolved by visibility, the same cheirality idea behind essential-matrix decomposition.

Worked numbers

Pure image translation by (2,1)(2, 1) is the homography with h13=2h_{13} = 2, h23=1h_{23} = 1, and last row (0,0,1)(0, 0, 1). Apply it to (3,4,1)(3, 4, 1):

Hx=(3+2, 4+1, 1)=(5,5,1)  →  (5,5)H x = (3 + 2,\ 4 + 1,\ 1) = (5, 5, 1) \;\to\; (5, 5)

Every point shifts identically, the signature of a translation. A tilt would instead show the bottom row bending parallels together toward a vanishing point.

Code

def apply_h(pt: tuple[float, float]) -> tuple[float, float]:    return (pt[0] + 2.0, pt[1] + 1.0)  # translation homography, last row (0, 0, 1)

print(apply_h((3.0, 4.0)))  # -> (5.0, 5.0)

Watch Out For

Fitting H to a non-flat scene

With real depth variation, no single HH aligns both the foreground and the background: warping by one plane ghosts the other. The symptom is double images after alignment that no amount of RANSAC tuning removes. Confirm planarity first; with parallax, graduate to two-view geometry via the fundamental matrix or stereo vision.

Trusting a decomposition without disambiguation

Decomposing HH returns multiple (R,t,n)(R, t, n) candidates, and most place the plane behind a camera or facing away. Accepting the first candidate flips the wall inside out. Keep only the solution with the plane visible in front of both views, exactly as the cheirality check does for EE.

The Quick Version

  • A homography is a 3×33 \times 3 matrix with 88 degrees of freedom mapping x′∼Hxx' \sim H x.
  • It holds for planar scenes and for pure camera rotations, and nothing else.
  • The plane-induced form H=R+tnT/dH = R + t n^T / d exposes the motion and the plane.
  • Fitting from point pairs belongs to homography estimation, linked above.
  • Decomposition needs a visibility check to pick the physical solution.
  • Parallax breaks single-HH alignment; that failure selects two-view geometry instead.