Pinhole camera model
The pinhole camera is the standard model for most cameras used in SLAM. Light from a 3D point passes through a small hole (the optical centre) and projects onto an image plane. The model describes image projection: how a point in the 3D world maps to a 2D pixel.
Coordinate Systems
Four coordinate systems are involved:
- World frame : fixed reference frame.
- Camera frame : is the optical axis (pointing forward).
- Image plane : metric coordinates on the image plane.
- Pixel frame : discrete pixel coordinates.
The usual convention is pointing right, pointing down, pointing forward — matching pixel coordinates (right) and (down) with the origin at the top-left corner of the image.
Projection Pipeline
Step 1: World to Camera. The rigid body transformation (extrinsic parameters) converts a world point to the camera frame:
Step 2: Camera to Image Plane (perspective division).
This division by depth is the source of perspective effects — and of the nonlinearity that makes vision geometry interesting. The coordinates are called normalized coordinates: they are what remains of a pixel once the intrinsics are stripped off, and most geometric derivations (essential matrix, triangulation) are cleanest in this frame.
Step 3: Image Plane to Pixel (intrinsic parameters).
where are focal lengths in pixels and is the principal point. The pixel focal length relates the physical focal length (in mm) to the pixel size: , which is why when pixels are not square.
Matrix Form
Combining all steps in homogeneous coordinates:
The matrix is the camera intrinsic matrix, and is the camera projection matrix. In the general case includes a skew parameter (usually zero for modern cameras).
A direct NumPy translation of the pipeline:
import numpy as np
def project(K, R, t, X_w):
X_c = R @ X_w + t # world -> camera
x_n = X_c[:2] / X_c[2] # perspective division (normalized coords)
u = K[0, 0] * x_n[0] + K[0, 2]
v = K[1, 1] * x_n[1] + K[1, 2]
return np.array([u, v])
Back-projection: the inverse is a ray
Projection destroys one dimension: a pixel does not determine a 3D point, only a ray. Given pixel , the ray of possible 3D points in the camera frame is
Recovering the missing depth is exactly what triangulation (multiple views), stereo (a second calibrated camera), or a depth sensor provides. The field of view follows from the same geometry: for image width .
Common pitfalls
- Axis conventions: computer vision uses forward / down; robotics (ROS) body frames use forward / up. Confusing them is the classic first bug when wiring a camera into a robot.
- Principal point is not the image centre: is close to but must be calibrated, not assumed.
- Forgetting the perspective division when implementing projection by hand — the homogeneous output of must be divided by its third component.
- Applying the model to distorted pixels: real images must be undistorted first (or the distortion model included in ); the pure pinhole equations only hold for ideal coordinates.
Why it matters for SLAM
The projection function defined by this model is at the heart of every visual SLAM system: the reprojection error minimized in bundle adjustment is nothing more than “project the map point with the pinhole model, compare against the measured pixel”. Triangulation, PnP, and epipolar geometry are all derived from the same equation, so deriving this pipeline from scratch is the single most valuable exercise at this level.