Skip to content
AI360Xpert
Beta

Camera Intrinsics: Focal Length and Center

A camera turns light rays into pixel numbers with four private numbers: two focal lengths and the pixel where the optical axis lands. Those four numbers are the intrinsics, and every measurement starts with them.

Intrinsics turn a ray through the optical center into a pixel: u equals f times X over Z plus c
Intrinsics turn a ray through the optical center into a pixel: u equals f times X over Z plus c

Why Does This Exist?

Two cameras photographing the same scene report different pixel numbers for the same 3D point, because their lenses and sensors differ. You cannot invert a single pixel back into a ray, compare two cameras, or measure anything in metric units until you know the four numbers that define the mapping from rays to pixels. Those numbers are the intrinsics.

The pinhole picture behind them lives in image formation and the camera model, and the full parameter map in camera calibration and parameters. This page covers one piece: what KK contains, what each entry does, and how to project one point by hand.

Think of It Like This

A projector running in reverse

A slide projector throws an image across the room. Move it further back and the picture grows: that throw distance is the focal length. Shift the projector sideways and the whole picture slides: that centering is the principal point.

A camera is the same machine in reverse. Light comes in through the lens instead of going out, but the throw distance still sets how big things land and the centering still sets where the middle lands. The analogy stops at the glass: a projector sheet is flat by design, while a real camera lens bends rays, which is the separate story of lens distortion.

How It Actually Works

Intrinsics live in the 3×33 \times 3 camera matrix KK. Here fxf_x and fyf_y are the focal lengths measured in pixels (one per axis, in case pixels are not perfectly square), and (cx,cy)(c_x, c_y) is the principal point, the pixel where the optical axis pierces the sensor:

K=[fx0cx0fycy001]K = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix}

In plain words: fxf_x says how many pixels one unit of slope buys you horizontally, and cxc_x says where slope zero lands. A camera-frame point (Xc,Yc,Zc)(X_c, Y_c, Z_c), meaning coordinates relative to the lens with ZcZ_c pointing forward, projects as u=fxXc/Zc+cxu = f_x X_c / Z_c + c_x and v=fyYc/Zc+cyv = f_y Y_c / Z_c + c_y. The division by depth ZcZ_c is the perspective part: twice as far means half as far from the center.

Worked numbers

Take fx=fy=800f_x = f_y = 800, (cx,cy)=(320,240)(c_x, c_y) = (320, 240), and the camera-frame point (Xc,Yc,Zc)=(1,2,4)(X_c, Y_c, Z_c) = (1, 2, 4):

u=800×1/4+320=200+320=520,v=800×2/4+240=400+240=640u = 800 \times 1 / 4 + 320 = 200 + 320 = 520, \qquad v = 800 \times 2 / 4 + 240 = 400 + 240 = 640

So the point lands on pixel (520,640)(520, 640). Move it to depth 88 and both offsets halve: (420,440)(420, 440). That halving is why depth can never be read back from one pixel alone, the scale ambiguity that structure from motion has to resolve.

Code

def project(x: float, z: float, f: float, c: float) -> float:    return f * x / z + c  # similar triangles, then shift to pixels

print(project(1.0, 4.0, 800.0, 320.0))  # -> 520.0print(project(2.0, 4.0, 800.0, 240.0))  # -> 640.0

Watch Out For

Reading focal length in millimetres

Datasheets quote lenses in millimetres, but KK wants pixels. The conversion is fx=fmm×(image width in pixels/sensor width in mm)f_x = f_{mm} \times (\text{image width in pixels} / \text{sensor width in mm}). Plug in 88 mm directly and every projection lands off by two orders of magnitude, which looks like a broken rotation rather than a units bug. Convert first, then project.

Assuming the principal point is the image center

The center pixel of a 640×480640 \times 480 image is (320,240)(320, 240), but manufacturing tolerances shift the true (cx,cy)(c_x, c_y) by several pixels. Treating the nominal center as truth injects a small constant bias into every back-projection, worst at the frame edges where rays are steepest. Calibrate it instead of assuming it; that is exactly what camera calibration measures.

The Quick Version

  • The intrinsic matrix KK holds focal lengths fxf_x and fyf_y plus the principal point (cx,cy)(c_x, c_y).
  • Projection divides by depth first, then scales and shifts: u=fxXc/Zc+cxu = f_x X_c / Z_c + c_x.
  • Focal length in KK is measured in pixels, never millimetres.
  • The principal point is near the image center but never exactly it.
  • One pixel cannot give depth back, because doubling depth halves the offset identically.