Disparity, depth & triangulation

Two cameras side by side see a point at slightly different positions. Once you know which pixels belong together, the two viewing rays meet at the point, and the shift between the pixels, the disparity, gives its depth. Drag the points, change the baseline and the focal length, and see how pixels, noise and wrong matches limit what stereo can measure.

Top view of the stereo rig drag PP and QQ shaded: visible in both images ◇ reconstructed point, filled area: all points with the same pair of pixels
The scanline in both images, 160160 pixels wide thin line: true position, colored cell: measured pixel
Depth change per pixel of disparity Z2/(f T)Z^2 / (f\,T) in m, over the depth ZZ in m PP QQ

Correspondence and reconstruction

A stereo system has to solve two problems:

This demo is about the second problem and assumes the simplest setup: both optical axes are parallel, both image planes lie in the same plane, and the scanlines are aligned, yL=yRy_L = y_R. A point can then only correspond to a point on the same scanline, and its two pixels differ only in xx. Other setups can be brought into this form by rectification.

Depth from disparity

Put the left center of projection at the origin and the right one at a distance TT, the baseline, along XX. Similar triangles give for both cameras

xLf=XZ  ⇒  X=xLZf,xRf=X−TZ  ⇒  X=xRZf+T\frac{x_L}{f} = \frac{X}{Z} \;\Rightarrow\; X = \frac{x_L Z}{f}, \qquad \frac{x_R}{f} = \frac{X - T}{Z} \;\Rightarrow\; X = \frac{x_R Z}{f} + T

Setting both equal and solving for ZZ:

xRZ=xLZ−f T⇒Z=f TxL−xR=f Tdx_R Z = x_L Z - f\,T \quad\Rightarrow\quad Z = \frac{f\,T}{x_L - x_R} = \frac{f\,T}{d}

The disparity d=xL−xRd = x_L - x_R is inversely proportional to the depth: near points have a large disparity, and d=0d = 0 means a point at infinity. Geometrically, Z=fT/dZ = fT/d is where the ray through xLx_L meets the ray through xRx_R.

Depth resolution and the baseline

Pixels have a width, so a pixel pair does not determine a point but a small area: the overlap of the two pixel wedges, shaded in the top view. Its depth extent follows from the derivative of Z=fT/dZ = fT/d:

∣∂Z∂d∣=f Td2=Z2f T\left| \frac{\partial Z}{\partial d} \right| = \frac{f\,T}{d^2} = \frac{Z^2}{f\,T}

The depth error for one pixel of disparity error grows with the square of the distance. A longer focal length or a longer baseline makes it smaller, so a small baseline gives a large depth error. A large baseline has its own problems: the search for correspondences covers more pixels, the two views look more different, and less of the scene is visible in both images, especially near the cameras.

Noise and wrong matches

Sensor noise, quantization and discretization shift the measured pixels, and each shift tilts a ray. Near the cameras, where the rays meet at a large angle, that barely moves the intersection; far away, where they are almost parallel, it moves it a lot. A wrong correspondence is worse: if the pixel of PP in the left image is matched with the pixel of QQ in the right image, the rays still meet, but at a point where there is nothing.

Try this