Foundations

Pinhole Camera Model

The ideal camera in which every scene point projects through a single center onto an image plane, giving the perspective projection x = fX/Z, y = fY/Z.

beginner

The pinhole camera model describes how a three-dimensional scene becomes a two-dimensional image when all light passes through a single point. It is the standard geometric camera model in computer vision, and real cameras are usually treated as pinhole cameras plus corrections.

Definition

A pinhole camera consists of a center of projection (the pinhole, also called the optical center or camera center) and an image plane at distance ff from it, the focal length. Every scene point is imaged where the straight line from the point through the center meets the image plane. The line through the center perpendicular to the image plane is the optical axis, and the point where it pierces the image plane is the principal point. The resulting mapping from 3D points to 2D image points is called perspective projection (or central projection).

Intuition

The physical version is the camera obscura: a dark box with a small hole in one wall. Light from each scene point reaches the opposite wall only along the ray through the hole, so the wall shows an inverted image of the outside. A larger hole blurs the image; a very small one makes it dim and, at the smallest sizes, blurred by diffraction. The model takes the limit of an infinitely small hole with no blur.

Geometrically it is equivalent, and more convenient, to place a virtual image plane at the same distance ff in front of the center. Rays from the scene cross this plane before reaching the center, and the image on it is upright. Almost all computer vision texts and libraries draw the model this way.

Formal Definition

Put the center of projection at the origin of a camera coordinate system whose ZZ axis is the optical axis, pointing into the scene, and place the image plane at Z=fZ = f. A scene point (X,Y,Z)(X, Y, Z) with Z>0Z > 0 and its image (x,y)(x, y) lie on the same ray through the origin, so by similar triangles

x=f XZ,y=f YZ.x = f\,\frac{X}{Z}, \qquad y = f\,\frac{Y}{Z}.

The division by ZZ makes the mapping nonlinear. In homogeneous coordinates it becomes a linear map, a 3×43 \times 4 projection matrix applied to the homogeneous 3D point:

λ[xy1]=[f0000f000010][XYZ1],λ=Z.\lambda \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} f & 0 & 0 & 0 \\ 0 & f & 0 & 0 \\ 0 & 0 & 1 & 0 \end{bmatrix} \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}, \qquad \lambda = Z.

The projective scale λ\lambda equals the depth of the point; dividing by it recovers the equations above. Hartley and Zisserman (2004) write this matrix as diag⁡(f,f,1) [ I∣0 ]\operatorname{diag}(f, f, 1)\,[\,I \mid \mathbf{0}\,], the starting point from which the general camera matrix is built.

Here (x,y)(x, y) are metric coordinates on the image plane with the origin at the principal point. Real images are indexed in pixels, with the origin at a corner (see digital image), and the camera is generally not at the world origin. Adding the conversion to pixels and an arbitrary camera pose turns this matrix into the full camera matrix P=K[R∣t]P = K[R \mid \mathbf{t}], described in camera intrinsic and extrinsic parameters.

Properties

Straight lines stay straight

A line in space and the camera center span a plane (unless the line passes through the center), which meets the image plane in a line, so perspective projection maps lines to lines. It does not preserve lengths, angles, or ratios of lengths; it preserves incidence and the cross-ratio, the invariants studied in projective geometry.

Parallel lines converge

Parallel lines in the scene generally meet in the image, at a vanishing point. A family of lines with direction d=(dX,dY,dZ)\mathbf{d} = (d_X, d_Y, d_Z) has points X0+s d\mathbf{X}_0 + s\,\mathbf{d}; as s→∞s \to \infty their images approach

v=(f dXdZ,  f dYdZ),\mathbf{v} = \left( f\,\frac{d_X}{d_Z},\; f\,\frac{d_Y}{d_Z} \right),

which depends only on the direction, not on X0\mathbf{X}_0: in homogeneous terms, v\mathbf{v} is the image of the point at infinity (dX,dY,dZ,0)(d_X, d_Y, d_Z, 0). Lines parallel to the optical axis vanish at the principal point. Lines parallel to the image plane (dZ=0d_Z = 0) stay parallel in the image; their vanishing point is a point at infinity. The vanishing points of all directions parallel to a ground plane lie on one line, the horizon.

Size falls off as 1/Z

An object of width WW at depth ZZ, facing the camera, has image width fW/ZfW/Z. Doubling the distance halves the image size. This is why the near face of a box looks larger than the far face.

Depth is lost

Every point on a ray through the center projects to the same image point, so a single image does not determine how far away a point is. Scaling the whole scene about the camera center by any k>0k > 0 leaves the image unchanged: a model car close by and a real car far away can produce identical pictures. Recovering depth requires extra information, such as a second view, known object sizes, or learned priors, and monocular structure from motion recovers the scene only up to an unknown global scale.

Field of view and focal length

For an image of width ww (in the same units as ff), the horizontal field of view is

θ=2arctan⁡ ⁣(w2f).\theta = 2 \arctan\!\left( \frac{w}{2f} \right).

A longer focal length gives a narrower field of view and magnifies the scene; a shorter one gives a wider view. Changing ff scales the whole image about the principal point but does not change relative sizes or occlusions, which are set by the camera position. The “compressed” look of telephoto photographs comes from standing far away, not from the focal length itself.

Relation to Real Cameras

Real cameras replace the pinhole with a lens to gather more light. An ideal thin lens with focal length ff brings rays from a point at distance zoz_o to a sharp focus at distance ziz_i behind it, where 1/zo+1/zi=1/f1/z_o + 1/z_i = 1/f. Only points at the focused distance are imaged as points; nearer and farther points spread into small blur circles. The aperture controls the trade-off: a smaller aperture behaves more like a pinhole, giving a larger depth of field (the range of distances that look acceptably sharp) but less light, while a larger aperture gathers more light at the cost of a shallower depth of field (Szeliski, 2022).

For geometry, a focused lens camera behaves like a pinhole camera whose center is the lens’s center of projection, with the image plane at the image distance ziz_i, which equals the nominal focal length only when focused at infinity. Two departures matter in practice. Real lenses bend straight lines, most visibly near the image borders of wide-angle lenses; this is modeled by lens distortion parameters applied on top of the pinhole projection, as OpenCV’s camera model does. And very wide fisheye lenses, with fields of view near or beyond 180°, cannot be described by a pinhole at all, because the pinhole image of rays at 90° to the axis lies at infinity; they need separate projection models.

Approximations

When the depth variation of an object is small compared with its distance, and the object lies close to the optical axis, the 1/Z1/Z factor is nearly constant across the object. Weak perspective replaces each point’s depth with the average depth Zˉ\bar{Z}:

x≈fZˉ X,y≈fZˉ Y.x \approx \frac{f}{\bar{Z}}\,X, \qquad y \approx \frac{f}{\bar{Z}}\,Y.

This is a uniform scaling of an orthographic view, and it is linear in (X,Y)(X, Y). Orthographic projection drops the scale altogether, x=Xx = X, y=Yy = Y, and models a camera infinitely far away with an infinitely long focal length. Both belong to the affine cameras, under which parallel lines stay parallel and there are no finite vanishing points (Hartley and Zisserman, 2004). They suit telephoto views of distant objects and simplify factorization-based structure from motion, but fail for scenes with a large depth range, such as a road receding to the horizon.

Coordinate Conventions

Libraries differ in how they orient the camera axes, and mixing them is a common source of bugs.

  • Computer vision (OpenCV): XX points right, YY points down, and ZZ points forward into the scene, matching image coordinates whose rows increase downward. The OpenCV documentation’s pinhole figure draws these axes, with the image plane at Z=fZ = f in front of the center.
  • Computer graphics (OpenGL): the camera looks along −Z-Z, with YY up and XX right. The gluLookAt reference page describes the viewing matrix as mapping the scene center to the negative zz axis and the up direction to the positive yy axis.

Both frames are right-handed, and converting camera coordinates from one to the other negates YY and ZZ, a rotation of 180° about the XX axis. Points in front of an OpenGL camera therefore have negative ZZ, and a pose estimated with OpenCV must be converted before it is used to render with a graphics engine.

Examples

The NumPy code below projects a 1 m cube with two focal lengths, checks the 1/Z1/Z falloff, walks along parallel edges to show them converging to a vanishing point, and confirms the scale ambiguity.

import numpy as np

def project(points, f):
    """Ideal pinhole: camera at the origin looking along +Z."""
    P = np.array([[f, 0, 0, 0],
                  [0, f, 0, 0],
                  [0, 0, 1, 0]], dtype=float)          # 3x4 projection
    Xh = np.hstack([points, np.ones((len(points), 1))])  # homogeneous 3D
    x = Xh @ P.T
    return x[:, :2] / x[:, 2:]                         # divide by Z

# A unit cube, 1 m wide, centred 0.5 m right of and 0.5 m above the axis
corners = np.array([[x, y, z] for z in (4.0, 5.0)
                    for y in (-1.0, 0.0) for x in (0.0, 1.0)])

for f in (1.0, 2.0):
    uv = project(corners, f)
    near, far = uv[:4], uv[4:]
    print(f"f = {f}: front face width {np.ptp(near[:, 0]):.3f}, "
          f"back face width {np.ptp(far[:, 0]):.3f}")

# Same object, twice as far away: image size halves (1/Z)
square = np.array([[0, 0, 4], [1, 0, 4]], float)
for scale in (1, 2):
    uv = project(square * [1, 1, scale], 1.0)
    print(f"Z = {4 * scale}: width {uv[1, 0] - uv[0, 0]:.3f}")

# The four edges parallel to Z run towards one image point
f = 2.0
K = np.diag([f, f, 1.0])
for d in (np.array([0.0, 0.0, 1.0]), np.array([1.0, 0.0, 1.0])):
    print("direction", d)
    for s in (0.0, 10.0, 1000.0):                      # walk along each edge
        uv = project(corners[:4] + s * d, f) + 0.0
        print(f"  s = {s:6.0f}:", np.round(uv, 3).tolist())
    v = K @ d
    print("  vanishing point K d:", (v[:2] / v[2]).tolist())

# Scale ambiguity: a cube twice as big and twice as far gives the same image
print("same image:", np.allclose(project(corners, f), project(2 * corners, f)))

Output:

f = 1.0: front face width 0.250, back face width 0.200
f = 2.0: front face width 0.500, back face width 0.400
Z = 4: width 0.250
Z = 8: width 0.125
direction [0. 0. 1.]
  s =      0: [[0.0, -0.5], [0.5, -0.5], [0.0, 0.0], [0.5, 0.0]]
  s =     10: [[0.0, -0.143], [0.143, -0.143], [0.0, 0.0], [0.143, 0.0]]
  s =   1000: [[0.0, -0.002], [0.002, -0.002], [0.0, 0.0], [0.002, 0.0]]
  vanishing point K d: [0.0, 0.0]
direction [1. 0. 1.]
  s =      0: [[0.0, -0.5], [0.5, -0.5], [0.0, 0.0], [0.5, 0.0]]
  s =     10: [[1.429, -0.143], [1.571, -0.143], [1.429, 0.0], [1.571, 0.0]]
  s =   1000: [[1.992, -0.002], [1.994, -0.002], [1.992, 0.0], [1.994, 0.0]]
  vanishing point K d: [2.0, 0.0]
same image: True

Doubling ff doubles every image coordinate, but the ratio of the back face to the front face stays at 4/54/5, the ratio of their depths, so perspective depends on distance, not focal length. The four edges along the optical axis converge on the principal point, and the four edges along the tilted direction (1,0,1)(1, 0, 1) converge on (fdX/dZ, fdY/dZ)=(2,0)(f d_X/d_Z,\, f d_Y/d_Z) = (2, 0), wherever they start. The YY values are negative for the top of the cube because YY points down in this convention.

Common Misconceptions

  • “The image in the model is upside down.” Only in the physical box. The standard model places a virtual image plane in front of the center, where the image is upright; the two are mathematically equivalent up to a sign.
  • “Focal length is a length in millimeters.” In the lens specification, yes. In vision equations ff is usually in pixels: the millimeter focal length divided by the pixel size. A 4 mm lens on a sensor with 2 µm pixels has f=2000f = 2000 pixels. Mixing the two units gives projections off by orders of magnitude.

Where It Is Used

Camera calibration estimates the parameters that connect the model to a real camera, namely its intrinsic and extrinsic parameters and its lens distortion. Two-view geometry, stereo depth estimation (through a cost volume of matching costs), structure from motion, and visual SLAM all relate image points in different views through pinhole projections, with correspondences from feature matching. Augmented reality projects virtual objects with the same model, and rasterization uses the same perspective projection in graphics conventions. Planar perspective image warping by a homography follows from it: two pinhole images of a plane, or two images from a camera rotating about its center, are related by a 3×33 \times 3 projective transform.

Related

  • Camera Intrinsic and Extrinsic Parameters

    The parameters of the pinhole camera matrix P = K[R | t], split into intrinsics K, which map camera coordinates to pixels, and extrinsics R and t, which place the camera in the world.

  • Projective Geometry

    The geometry of properties that survive perspective projection, such as straightness, incidence, and the cross-ratio, which underlies how computer vision models cameras and relates images.

  • Lens Distortion

    The systematic deviation of a real lens from the pinhole model's straight-line projection, which bends straight lines in the image and is modeled, estimated, and removed as part of camera calibration.

  • Digital Image

    A digital image is a grid of samples of a continuous scene, each quantized to a finite set of values and stored as an array of numbers.

  • Image Warping

    Transforming the geometry of an image by a coordinate mapping, usually computed by sampling the input image at the inverse-mapped position of every output pixel.

References

  1. Hartley, R. & Zisserman, A. (2004). Multiple View Geometry in Computer Vision (2nd ed.). Cambridge University Press.
  2. Szeliski, R. (2022). Computer Vision: Algorithms and Applications (2nd ed.). Springer.
  3. OpenCV. Camera Calibration and 3D Reconstruction (calib3d module documentation), OpenCV 4.x.
  4. Khronos Group. gluLookAt. OpenGL 2.1 Reference Pages.