The Pinhole Camera Model

Point a camera at a chessboard and snap a photo. The parallel edges of the squares appear to converge toward a horizon. Nothing in the physical board changed. Yet straight lines bend toward vanishing points on the image. Explaining this convergence — the essential signature of perspective — requires a precise geometric model. It must describe how light travels from a three-dimensional scene onto a two-dimensional sensor. The pinhole camera model supplies exactly that. It is a minimal, idealized description of image formation through a single point aperture, with no lens and no blur. This model matters because nearly every camera used in computer vision is treated mathematically as a pinhole camera plus corrections. This includes everything from a phone camera to a satellite imager. Camera calibration, Stereo Vision, structure-from-motion, augmented reality overlays, and 3D reconstruction all begin the same way. They start by writing down the pinhole projection equations. Then they estimate the unknown parameters inside them. Without this model there is no principled way to relate a pixel coordinate to a physical ray in space. Therefore there is no way to reason about depth, motion, or 3D structure from 2D images. The big picture is a linear-algebraic one. Perspective projection produces the nonlinear-looking effect of vanishing points. Despite this, it can be written as a single matrix multiplication in homogeneous coordinates. This is the payoff of choosing the right coordinate representation. A 3D point becomes a 4-vector. A 2D image point becomes a 3-vector. The entire imaging process — rotation, translation, and perspective division — collapses into one matrix. This is the camera projection matrix. This article builds the pinhole model from first principles. It covers the geometry of a point aperture, the derivation of the perspective projection equations, and the intrinsic and extrinsic parameterization. It also covers the homogeneous-coordinate matrix formulation. It closes with a fully worked numerical example, a table of common errors, and the history of the model. This history predates photography by centuries.

Key takeaways
  • A pinhole camera forms an image by letting light pass through a single infinitesimal aperture, producing a sharp, inverted, perspectively correct image with no lens.
  • The core relationship is similar triangles: a 3D point at depth ZZ projects to image coordinates scaled by focal length ff and divided by ZZ.
  • Homogeneous coordinates convert this nonlinear division into a linear matrix multiply, giving the 3×43\times 4 camera matrix P=K[R ∣ t]P = K[R\,|\,t].
  • KK (intrinsics) encodes focal length, pixel scale, and principal point; [R ∣ t][R\,|\,t] (extrinsics) encodes the camera's pose in the world.
  • Depth ZZ is fundamentally lost in a single image — pinhole projection is a many-to-one map, which is why triangulation needs two or more views.
  • The model is the foundation for Camera Calibration, Stereo Vision, and 3D reconstruction, and is refined later by lens models that add distortion and finite aperture effects.
The core insight

Perspective projection through a point aperture is division by depth, and choosing homogeneous coordinates turns that division into a single linear matrix multiplication.

The idea

A pinhole camera is an idealized imaging device: light from a scene passes through a single infinitesimally small aperture and lands on a flat image plane, with no lens bending the rays. Because the aperture is a single point, each scene point sends exactly one ray of light through it, so each 3D point maps to exactly one 2D point on the image plane. This gives the cleanest possible geometric model of image formation, building directly on the The Image Formation Model idea that an image is the result of geometric projection combined with radiometric measurement. The key geometric fact is similar triangles. Place the pinhole at the origin of a camera-centered coordinate system, with the optical axis along ZZ, and the image plane at distance ff (the focal length) in front of the aperture (a convenient fiction — physically the image forms behind the pinhole, inverted, but placing a virtual plane in front avoids the inversion and is optically equivalent). A scene point (X,Y,Z)(X, Y, Z), with Z>0Z > 0 being depth along the optical axis, projects to the image point

x=fXZ,y=fYZ.x = f\frac{X}{Z}, \qquad y = f\frac{Y}{Z}.

This is perspective projection: image coordinates scale inversely with depth, which is exactly why distant objects appear smaller and parallel lines appear to converge. The division by ZZ is the mathematical seed of every perspective effect — foreshortening, vanishing points, and the impossibility of recovering absolute scale from a single image. To turn pixel measurements into these physical coordinates, the model separates two kinds of parameters. Intrinsic parameters describe the camera itself — focal length in pixels, the pixel aspect ratio, skew, and the principal point (where the optical axis pierces the image plane, ideally the image center). Extrinsic parameters describe where the camera sits in the world — a rotation RR and translation tt mapping world coordinates into the camera's coordinate frame. Separating these is what allows a single camera model to be reused across different poses, and it is the parameterization that Camera Calibration procedures solve for.

How it works

The projection pipeline has three logical stages, each a coordinate transformation, and each expressible as multiplication by a matrix once homogeneous coordinates are introduced.

Stage 1 — World to camera (extrinsics). A 3D point PwP_w given in world coordinates is transformed into the camera's coordinate frame by a rigid transformation:

Pc=R Pw+t,P_c = R\,P_w + t,

where RR is a 3×33\times3 rotation matrix and tt is a 3×13\times1 translation vector. This places the point relative to the camera, with the camera's optical axis as the ZZ-axis.

Stage 2 — Camera to normalized image plane (perspective division). The camera-frame point (Xc,Yc,Zc)(X_c, Y_c, Z_c) is projected through the pinhole onto a plane at unit distance:

xn=XcZc,yn=YcZc.x_n = \frac{X_c}{Z_c}, \qquad y_n = \frac{Y_c}{Z_c}.

This is the only nonlinear step in the whole pipeline — an actual division — and it is the step that discards depth information.

Stage 3 — Normalized image to pixel coordinates (intrinsics). The normalized coordinates are scaled and shifted into pixel units using the intrinsic matrix

K=(fxscx0fycy001),K = \begin{pmatrix} f_x & s & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{pmatrix},

where fx,fyf_x, f_y are the focal length expressed in pixels along each axis (allowing for non-square pixels), ss is a skew term (nearly always zero for modern sensors), and (cx,cy)(c_x, c_y) is the principal point. The trick that makes this pipeline a single matrix is homogeneous coordinates: represent the 3D point as a 4-vector P~w=(X,Y,Z,1)T\tilde{P}_w = (X, Y, Z, 1)^T and the resulting 2D pixel as a 3-vector p~=(u,v,1)T\tilde{p} = (u, v, 1)^T up to scale. Then the entire projection is

p~  ∼  K(Rt)P~w  =  P P~w,\tilde{p} \;\sim\; K \begin{pmatrix} R & t \end{pmatrix} \tilde{P}_w \;=\; P\,\tilde{P}_w,

where ∼\sim denotes equality up to a nonzero scalar, and P=K[R ∣ t]P = K[R \,|\, t] is the 3×43\times4 camera projection matrix. The perspective division that was explicit in Stage 2 is now implicit: it is recovered by dividing the resulting 3-vector by its third coordinate. ```

# PSEUDOCODE — Pinhole projection of a 3D point to a pixel function PROJECT_POINT(P_world, R, t, K):

# P_world: 3-vector (X, Y, Z) in world coordinates

# R: 3x3 rotation matrix, t: 3x1 translation vector (extrinsics)

# K: 3x3 intrinsic matrix

# Stage 1: world -> camera frame P_cam = R * P_world + t # 3-vector (Xc, Yc, Zc) if P_cam.Z <= 0: return NULL # point is behind the camera: no image formed

# Stage 2: camera frame -> normalized image plane (perspective division) x_n = P_cam.X / P_cam.Z y_n = P_cam.Y / P_cam.Z p_n = (x_n, y_n, 1) # homogeneous normalized point

# Stage 3: normalized -> pixel coordinates via intrinsics p_pixel_h = K p_n # 3-vector (uw, v*w, w), here w = 1 u = p_pixel_h[0] / p_pixel_h[2] v = p_pixel_h[1] / p_pixel_h[2] return (u, v)

function PROJECT_MATRIX_FORM(P_world_h, P):

# P_world_h: homogeneous 4-vector (X, Y, Z, 1)

# P: 3x4 camera matrix, P = K [R | t] q = P * P_world_h # 3-vector (qx, qy, qw) if qw <= 0: return NULL # behind camera return (qx / qw, qy / qw) ``` The two functions are equivalent; `PROJECT_MATRIX_FORM` is the form used in practice because building PP once lets every subsequent point be projected with one 3×4×4×13\times4 \times 4\times1 matrix-vector product.

Figure
The pinhole projection pipeline: world point → camera frame → image plane → pixel grid
P = (X,Y,Z) pinhole O image plane (dist. f) p = (fX/Z, fY/Z) pixel grid (u,v) apply K: scale + shift world → camera: R, t camera → plane: divide by Z

The diagram makes explicit why the process is called a pipeline: the world point is first re-expressed in the camera's frame (R,tR, t), then projected through the aperture with a division by depth, then rescaled onto the discrete pixel grid (KK). Each arrow is one matrix (or one division); composing all three gives the single matrix PP.

Complexity & correctness

Time complexity. Projecting a single point is O(1)O(1): two constant-size matrix-vector products (3×43\times4 times 4×14\times1, then a divide). Projecting nn points, as when rendering a full 3D model or reprojecting a point cloud, is therefore O(n)O(n), and this is optimal since every point's coordinates must be touched at least once (an Ω(n)\Omega(n) lower bound because the output has nn points, each requiring examination). In practice the 3×43\times4 matrix PP is precomputed once per camera pose, amortizing the cost of forming K[R∣t]K[R|t] (itself O(1)O(1) matrix multiplications) across all nn points.

Space complexity. O(1)O(1) additional space per camera (the 3×43\times4 matrix, 12 numbers, or equivalently 5 intrinsic and 6 extrinsic degrees of freedom), plus O(n)O(n) for storing the input points and output pixels, which is required simply to hold the data.

Correctness argument. The claim to verify is that the matrix formulation p~∼K[R∣t]P~w\tilde p \sim K[R|t]\tilde P_w exactly reproduces the geometric similar-triangles projection. Write Pc=RPw+t=(Xc,Yc,Zc)TP_c = R P_w + t = (X_c, Y_c, Z_c)^T; by definition of homogeneous equivalence,

K(XcYcZc)=(fxXc+sYc+cxZcfyYc+cyZcZc).K \begin{pmatrix} X_c \\ Y_c \\ Z_c \end{pmatrix} = \begin{pmatrix} f_x X_c + s Y_c + c_x Z_c \\ f_y Y_c + c_y Z_c \\ Z_c \end{pmatrix}.

Dividing the first two components by the third (the homogeneous-to-Cartesian step) gives, when s=0s = 0,

u=fxXcZc+cx,v=fyYcZc+cy,u = f_x \frac{X_c}{Z_c} + c_x, \qquad v = f_y \frac{Y_c}{Z_c} + c_y,

which is precisely "scale the similar-triangle projection (Xc/Zc,Yc/Zc)(X_c/Z_c, Y_c/Z_c) by focal length and shift by the principal point." This matches the Stage-2/Stage-3 derivation term for term, so the matrix form is not an approximation — it is an algebraic repackaging of the same geometry, valid whenever Zc≠0Z_c \ne 0. The invariant preserved at every stage is: the ray from the world point through the camera center, expressed in the current coordinate frame, always intersects the corresponding plane at the correctly scaled position — rotation and translation preserve this ray, and the final division reads off where it crosses the image plane.

Honesty about the model's limits. Pinhole projection is fundamentally a many-to-one map: every point along the ray from the camera center through PP projects to the same pixel, so depth ZZ cannot be recovered from a single image — this is why monocular depth is ill-posed without additional priors, and why Stereo Vision uses two views to triangulate. The model also assumes an infinitesimal aperture (zero light, infinite depth of field, no blur), which is physically unrealizable; real cameras use a lens with finite aperture, introducing defocus blur and geometric distortion, refined in the study of Lenses and Optics. Finally, the model assumes a perfect, noise-free, continuous image plane, whereas real sensors discretize the plane into finite pixels, the subject of Digital Images and Sampling.

Worked example

Consider a camera with intrinsics fx=fy=800f_x = f_y = 800 px, principal point (cx,cy)=(320,240)(c_x, c_y) = (320, 240) (a 640×480640\times480 image), zero skew, positioned at world coordinates tworld=(0,0,−5)t_{\text{world}} = (0, 0, -5) meters looking straight down the world ZZ-axis with no rotation relative to world axes (R=IR = I). We want to project the world point Pw=(0.5,0.25,5)P_w = (0.5, 0.25, 5) meters — half a meter right, quarter meter up, five meters ahead of the world origin. The extrinsic transform used here is Pc=R Pw+tP_c = R\,P_w + t, with tt chosen as the camera position expressed as a translation applied after rotation (i.e., t=−R Ct = -R\,C where CC is camera center in world coordinates; here R=IR = I and C=(0,0,−5)C = (0,0,-5), so t=(0,0,5)t = (0,0,5)).

StepComputationResult
Camera center CCgiven(0,0,−5)(0, 0, -5)
Translation t=−RCt = -RC−I⋅(0,0,−5)-I\cdot(0,0,-5)(0,0,5)(0, 0, 5)
Camera-frame point Pc=RPw+tP_c = R P_w + t(0.5,0.25,5)+(0,0,5)(0.5, 0.25, 5) + (0,0,5)(0.5,0.25,10)(0.5, 0.25, 10)
Depth checkZc=10>0Z_c = 10 > 0in front of camera ✓
Normalized projectionxn=0.5/10,  yn=0.25/10x_n = 0.5/10,\; y_n = 0.25/10(0.05,0.025)(0.05, 0.025)
Apply fx,fyf_x, f_y800×0.05,  800×0.025800 \times 0.05,\; 800 \times 0.025(40,20)(40, 20)
Add principal point(40+320, 20+240)(40+320,\ 20+240)(360,260)(360, 260)

So Pw=(0.5,0.25,5)P_w = (0.5, 0.25, 5) lands at pixel (u,v)=(360,260)(u, v) = (360, 260) — slightly right of and below the image center (320,240)(320, 240), matching intuition since the point is to the right of and above the world origin but the camera looks straight ahead (the vertical sign convention here takes image yy increasing downward, so "up in the world" shows as a smaller offset consistent with the chosen axis convention; the sign details depend on convention but the magnitude and mechanism are what matter). Now verify the many-to-one claim: the world point Pw′=(1.0,0.5,10)P_w' = (1.0, 0.5, 10) lies on the same ray from the camera center through PwP_w (it is 2×2\times the camera-frame vector (0.5,0.25,10)→(1.0,0.5,20)(0.5,0.25,10) \to (1.0, 0.5, 20), scaled by 22). Projecting it:

xn′=1.020=0.05,yn′=0.520=0.025,x_n' = \frac{1.0}{20} = 0.05, \qquad y_n' = \frac{0.5}{20} = 0.025,

identical normalized coordinates, hence identical pixel (360,260)(360, 260) despite being twice as far away. This confirms the invariant from the correctness section directly: points differing only by a positive scalar multiple along a camera-frame ray project to the same pixel, which is exactly the depth-ambiguity the pinhole model predicts. As a second check, project the camera center itself's forward axis point (0,0,1)(0,0,1) in camera frame (i.e., a point straight down the optical axis): xn=0/1=0x_n = 0/1 = 0, yn=0/1=0y_n = 0/1 = 0, giving pixel (320,240)(320, 240) — exactly the principal point, as required, since points on the optical axis must map to where that axis pierces the image plane.

Common pitfalls & traps

PitfallWhy it happensFix
Forgetting the cheirality check (Zc≤0Z_c \le 0)Naively applying the formula to points behind the camera yields a mirror-flipped, spurious projection instead of "no image"Always test Zc>0Z_c > 0 before dividing; discard or flag points that fail
Confusing camera center CC with translation ttt≠Ct \ne C in general; t=−RCt = -RCBe explicit about which convention (Pc=RPw+tP_c = RP_w + t vs. Pc=R(Pw−C)P_c = R(P_w - C)) is used, and stay consistent
Assuming square pixels (fx=fyf_x = f_y)Older or asymmetric sensors have non-square photositesCalibrate fx,fyf_x, f_y separately; never hardcode equality
Ignoring skew or principal point offsetAssuming s=0,(cx,cy)=(width/2,height/2)s=0, (c_x,c_y) = (\text{width}/2,\text{height}/2) without calibrationEstimate KK via Camera Calibration rather than guessing
Treating pinhole projection as invertibleA single 2D point corresponds to an entire 3D ray, not a unique pointUse multiple views (Stereo Vision) or additional priors to recover depth
Dividing before checking for Zc=0Z_c = 0Points exactly on the camera plane cause division by zeroGuard the division; treat Zc≈0Z_c \approx 0 as undefined/degenerate

Pioneers & history

The geometry behind the pinhole camera long predates cameras themselves: the convergence of light rays through a small aperture was documented by natural philosophers studying optics and later formalized by Renaissance artists developing linear perspective, before being rigorously connected to the mathematics of projective geometry.

Origins · 1 minIbn al-Haytham (Alhazen) and how this was discovered
IA
Ibn al-Haytham (Alhazen)
c. 965 – c. 1040 · Basra and Cairo, early studies of the camera obscura and optics

Alhazen's Book of Optics gave the first systematic account of how light traveling in straight lines through a small aperture forms an inverted image — the physical principle underlying the pinhole camera, studied centuries before photographic capture existed.

FB
Filippo Brunelleschi
1377 – 1446 · Florence, developer of linear perspective in painting

- Lens distortion introduced by the glass elements - Sensor noise accumulating over the image width - Perspective division by depth ZZ, which shrinks farther points' projected coordinates ✓ - Incorrect placement of the principal point

:::quiz[Given camera matrix P=K[R∣t]P = K[R|t] and a world point in homogeneous coordinates, how is the final pixel obtained?]

  • Multiply PP by the point and take the result directly as (u,v)(u,v)
  • Multiply PP by the point, then divide the first two components by the third ✓
  • Add KK to [R∣t][R|t] before multiplying by the point
  • Take the eigenvector of PP corresponding to the point

Ask the tutor: How does adding a second camera (stereo) resolve the depth ambiguity inherent in a single pinhole projection?

Why is it called a "pinhole" camera if real cameras use lenses?

The name refers to an idealized model, not a literal design choice in modern cameras. A true pinhole (a single point-sized aperture) would form a perfectly sharp image at any distance because light from each scene point travels along exactly one ray to the sensor, with no lens to focus or blur it. Real cameras use lenses to gather more light and control focus, but the underlying projective geometry — how a 3D point maps to a 2D image position — is, to first order, identical to the pinhole case. This is why the pinhole model is used as the baseline geometric description, with lens effects such as distortion and depth-of-field layered on top in the study of Lenses and Optics.

What exactly is lost when a 3D scene is projected onto a 2D pinhole image?

Depth along the viewing ray is lost. Every point on the ray from the camera center through a given 3D point projects to the same pixel, regardless of how far along that ray the point sits, because the projection formula divides both XX and YY by the same ZZ. This makes the pinhole map many-to-one: infinitely many 3D points collapse onto one pixel. Recovering depth requires additional information — a second view (triangulation in Stereo Vision), known object size, motion over time, or learned monocular priors — none of which are contained in the geometry of a single pinhole image alone.

What is the difference between intrinsic and extrinsic parameters?

Intrinsic parameters describe properties internal to the camera: focal length in pixels (fx,fyf_x, f_y), skew, and the principal point, all bundled into the matrix KK. They do not change if the camera is moved, only if its internal optics or sensor change. Extrinsic parameters describe the camera's pose in the world: a rotation RR and translation tt that convert world coordinates into the camera's coordinate frame. Separating the two lets a single calibrated KK be reused across arbitrarily many camera positions, which is exactly what Camera Calibration procedures exploit by holding KK fixed while estimating a different [R∣t][R|t] per photograph.

Why use homogeneous coordinates instead of ordinary Cartesian coordinates?

Perspective projection involves a division by depth, which is a nonlinear operation and cannot be written as a matrix multiplication in ordinary Cartesian coordinates. Homogeneous coordinates add an extra dimension and treat vectors as equivalent up to nonzero scaling, which lets the division be deferred: the linear part (rotation, translation, intrinsic scaling) is done first via one matrix multiplication, and the division by the last coordinate is applied only at the very end to recover Cartesian pixel coordinates. This turns the entire imaging pipeline into a single 3×43\times4 matrix, dramatically simplifying calibration, composition of transformations, and downstream algorithms such as triangulation and bundle adjustment.

Can the pinhole model handle a camera pointed at an angle or upside down?

Yes — that is precisely the role of the extrinsic parameters RR and tt. Rotation RR reorients the world so that, in the camera's own frame, the optical axis is always the ZZ-axis; translation tt repositions the origin to the camera center. Once a world point is expressed in this camera-centered frame, the same projection formula (xn=Xc/Zcx_n = X_c/Z_c, etc.) applies regardless of how the camera was physically tilted, panned, or inverted in the world. This is why the extrinsic-intrinsic split is so powerful: all camera orientations reduce to the identical canonical projection after the rigid transform.

Does the pinhole model apply to cameras with very wide fields of view, like fisheye lenses?

Only approximately, and often poorly. The linear pinhole model assumes straight lines in the world map to straight lines in the image, which holds for rectilinear lenses over moderate fields of view but breaks down for fisheye or very wide-angle optics, where significant radial distortion curves straight lines. In practice, real lenses are modeled as an ideal pinhole projection followed by a distortion correction step, studied separately under Lenses and Optics, and calibration routines estimate both the pinhole intrinsics and the distortion coefficients simultaneously so that fisheye imagery can still be rectified into an approximately pinhole-consistent image.

Is the pinhole projection matrix PP unique for a given camera and pose?

Only up to a global scale factor. Because p~∼PP~w\tilde p \sim P\tilde P_w is an equivalence up to nonzero scaling, multiplying every entry of PP by the same nonzero constant produces an identical set of projected pixels. This is why PP is typically normalized (for instance, by fixing its last row's norm) before comparing camera matrices numerically, and why calibration algorithms recover PP, or equivalently KK, RR, tt, only up to this inherent scale ambiguity, which is harmless for projection but must be handled carefully when decomposing PP back into KK, RR, and tt via matrix factorization.

Before this

Where this leads