DLT camera calibration

Calibrating a camera means estimating its intrinsics KK and pose [R∣t][R \mid t]. Photograph a target with known 3D geometry, find its corners in the image, and the projection matrix M=K[R∣t]M = K[R \mid t] follows from a linear system. Add noise, drop points and switch methods, and compare the recovered camera with the true one.

Camera image measured corners reprojected with M^\hat M error, magnified
Calibration target and cameras true camera CC estimated C^\hat C drag to orbit, scroll to zoom
Singular values σk\sigma_k of AA (log scale; for Ax=0Ax = 0 the red one belongs to the solution)

Calibration with a known target

A pinhole camera maps a world point to a pixel with one 3 × 4 matrix:

w[uv1]=[m11m12m13m14m21m22m23m24m31m32m33m34]⏟M = K[R∣t][XYZ1],K=[αsu00βv0001]w \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \underbrace{\begin{bmatrix} m_{11} & m_{12} & m_{13} & m_{14} \\ m_{21} & m_{22} & m_{23} & m_{24} \\ m_{31} & m_{32} & m_{33} & m_{34} \end{bmatrix}}_{M \,=\, K[R \mid t]} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}, \qquad K = \begin{bmatrix} \alpha & s & u_0 \\ 0 & \beta & v_0 \\ 0 & 0 & 1 \end{bmatrix}

The target here is the classic calibration rig: two perpendicular checkerboards, 5 cm squares, in the planes Y=0Y = 0 and X=0X = 0 of a world frame with ZZ up. Its inner corners have known coordinates (X,Y,Z)(X, Y, Z), and their pixels (u,v)(u, v) are measured in the image, here with Gaussian noise of σ\sigma pixels.

Two equations per point

Dividing by ww gives the pixel, and multiplying the denominator out gives equations linear in MM:

u=m11X+m12Y+m13Z+m14m31X+m32Y+m33Z+m34  ⇒  m11X+m12Y+m13Z+m14−m31uX−m32uY−m33uZ−m34u=0u = \frac{m_{11} X + m_{12} Y + m_{13} Z + m_{14}}{m_{31} X + m_{32} Y + m_{33} Z + m_{34}} \;\Rightarrow\; m_{11} X + m_{12} Y + m_{13} Z + m_{14} - m_{31} u X - m_{32} u Y - m_{33} u Z - m_{34} u = 0

and likewise for vv. MM has 12 entries, but like every projective matrix it is only defined up to scale, which leaves 11 unknowns. Each point gives two equations, so 5.5 points determine MM: at least 6 are needed. More points make the system overdetermined, and least squares finds the MM that fits them best, which makes the result robust to errors in the measured corners.

Method 1: Ax=bAx = b

Fix the scale by setting m34=1m_{34} = 1. The terms with m34m_{34} move to the right-hand side, and the system has 11 unknowns:

[X1Y1Z110000−u1X1−u1Y1−u1Z10000X1Y1Z11−v1X1−v1Y1−v1Z1⋮⋮][m11m12⋮m33]=[u1v1⋮]\begin{bmatrix} X_1 & Y_1 & Z_1 & 1 & 0 & 0 & 0 & 0 & -u_1 X_1 & -u_1 Y_1 & -u_1 Z_1 \\ 0 & 0 & 0 & 0 & X_1 & Y_1 & Z_1 & 1 & -v_1 X_1 & -v_1 Y_1 & -v_1 Z_1 \\ \vdots & & & & & & & & & & \vdots \end{bmatrix} \begin{bmatrix} m_{11} \\ m_{12} \\ \vdots \\ m_{33} \end{bmatrix} = \begin{bmatrix} u_1 \\ v_1 \\ \vdots \end{bmatrix}

AA is 2n×112n \times 11, and the least-squares solution is x=(A⊤A)−1A⊤bx = (A^\top A)^{-1} A^\top b, as for vertical least squares. The catch is m34m_{34}: it equals tzt_z, the depth of the world origin in front of the camera. If the world origin lies near the plane through the camera center parallel to the image, m34≈0m_{34} \approx 0, and forcing it to 1 needs an enormous scale for all other entries. Here the origin, the inner corner of the rig, is well in front of the camera.

Method 2: Ax=0Ax = 0

Keep all 12 entries, with the last column −ui-u_i, −vi-v_i, and look for the unit vector xx that makes ∣Ax∣|Ax| smallest: the right singular vector of the smallest singular value of the 2n×122n \times 12 matrix AA, the last column of VV in the SVD, as in total least squares and for a homography. Without noise, σ12=0\sigma_{12} = 0; with noise it measures how well the points agree with a single MM.

The target must not be flat. All points of one plane satisfy a linear equation, so adding any multiple of that equation to a row of MM changes nothing for them: three extra directions besides the scale. Four singular values drop to zero, and the solution is an arbitrary vector of this four-dimensional null space rather than K[R∣t]K[R \mid t]. For the board in the plane Y=0Y = 0, the columns of m12m_{12}, m22m_{22} and m32m_{32} are all zero, and a vector with only m32=1m_{32} = 1 satisfies every equation as 0=00 = 0, while sending every point to w=0w = 0. That is why the rig has two boards.

Factorizing MM back into K[R∣t]K[R \mid t]

The left 3 × 3 block of MM is Q=KRQ = KR: an upper triangular matrix times a rotation. The RQ decomposition splits a matrix exactly into these two factors: the upper triangular one is KK, the orthogonal one is RR. Here it is computed with three Givens rotations that zero the entries below the diagonal. The decomposition leaves signs open, so it needs post-processing to give valid matrices: the diagonal of KK is made positive, MM is negated if RR comes out as a reflection (the SVD can return −M-M just as well as MM), and KK is scaled to K33=1K_{33} = 1. The last column of MM is m4=Ktm_4 = Kt, so

t=K−1m4t = K^{-1} m_4

Recovering the camera center

The camera center is not tt: the point is rotated before the translation is added. The center is the point that MM maps to 0, RC+t=0R C + t = 0, so

C=−R−1t=−R−1K−1m4=−Q−1m4C = -R^{-1} t = -R^{-1} K^{-1} m_4 = -Q^{-1} m_4

which needs neither the RQ decomposition nor the scale of MM.

Linear calibration and beyond

The linear method is easy to set up and solve, and it needs no initial guess. But it only gives MM, and the camera parameters have to be extracted from it. It does not model radial lens distortion, and it cannot impose constraints such as zero skew or square pixels: s^\hat s comes out as whatever fits the noise best. It also minimizes an algebraic error ∣Ax∣|Ax|, not the distance in pixels. In practice the linear result is the starting point for a non-linear method, which defines the error as the difference between the projected and the measured points and minimizes it with Newton's method or a similar optimizer.

Try this