Homogeneous Coordinates and Transformation Matrices

Homogeneous Coordinates and Transformation Matrices

What are homogeneous coordinates?

Homogeneous coordinates are a coordinate system used in projective geometry, obtained by augmenting ordinary (Cartesian) coordinates with one extra coordinate. Strictly speaking they form an equivalence class in which proportional coordinates $(kx, ky, kw) \sim (x, y, w)$ (for $k \neq 0$) denote the same point, which is exactly what lets us express every transformation, including translation, as a single matrix product.

2D point (x, y) Cartesian Homogeneous (x, y, 1) 3-component vector 3D: (X, Y, Z) → homog.: (X, Y, Z, 1) scale-invariant: (kx, ky, k) ∼ (x, y, 1)
Figure 1. Correspondence between Cartesian and homogeneous coordinates.

Definition of homogeneous coordinates

  • Homogeneous coordinates of a 2D point $(x, y)$: $(x, y, 1)$, or more generally $(kx, ky, k)$ for $k \neq 0$
  • Homogeneous coordinates of a 3D point $(X, Y, Z)$: $(X, Y, Z, 1)$, or $(kX, kY, kZ, k)$
  • Back to Cartesian coordinates: $(x, y, w) \to (x/w, y/w)$

Why use homogeneous coordinates?

  • Translation can be written as a matrix product
  • Several transforms can be composed into a single matrix
  • Projective transforms (perspective projection) can be handled linearly
  • Points at infinity can be represented with finite coordinates ($w = 0$)

Why translation is special

In Cartesian coordinates, translation is an addition $(x', y') = (x, y) + (t_x, t_y)$ and cannot be written as a single matrix product (a linear map always fixes the origin). Adding one extra dimension via homogeneous coordinates lets us write translation as a single matrix product $(x', y', 1) = T\,(x, y, 1)$, so rotation, scaling, and translation can all be composed within the same framework — this is the key benefit.

2D transformation matrices

Vector convention: vectors are treated as column vectors, and transforms multiply on the left, $p' = T\,p$. Writing $(x, y, 1)$ as a comma-separated row is just shorthand for the column vector $(x, y, 1)^\top$, written horizontally to save space instead of stacking it vertically.

Translation

original translated (tx, ty) Translation matrix: T = 10tx 01ty 001 p′ = T p (x′, y′, 1) = (x+tx, y+ty, 1)
Figure 2. Translation transformation matrix.

Rotation

θ rotate about origin Rotation matrix: R = cos θ−sin θ0 sin θcos θ0 001 CCW is taken as positive
Figure 3. Rotation about the origin.

Scaling

sx = 2, sy = 3 Scale matrix: S = sx00 0sy0 001 sx ≠ sy: anisotropic scale
Figure 4. Effect of the scaling transformation.

Composing transformations

Several transforms can be composed into a single matrix product. Note that they are applied from right to left.

Composition of transforms

Applying scale → rotation → translation in that order:

$$M = T \cdot R \cdot S$$ $$\mathbf{p}' = M \mathbf{p} = T(R(S \mathbf{p}))$$
original S scaled R rotated T translated
Figure 5. Composition of geometric transforms (scale → rotation → translation).

Important: matrix multiplication is non-commutative ($AB \neq BA$). Applying the transforms in a different order gives a different result.

3D transformation matrices

Transforms in 3D space are represented by $4 \times 4$ matrices.

3D translation

$$T = \begin{pmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

3D rotation matrices

About the X-axis (roll):

$$R_x(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

About the Y-axis (pitch):

$$R_y(\theta) = \begin{pmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$

About the Z-axis (yaw):

$$R_z(\theta) = \begin{pmatrix} \cos\theta & -\sin\theta & 0 & 0 \\ \sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{pmatrix}$$
A single 3D diagram of rotations about the X, Y, and Z axes, with a right-hand-rule rotation arrow around each axis Pitch (Y-axis) Roll (X-axis) Yaw (Z-axis)
Figure 6. Three-axis rotation (Roll, Pitch, Yaw) — each orange arrow follows the right-hand (counterclockwise) direction.

Note (limitations of Euler angles): Roll, Pitch, and Yaw come from aerospace terminology; in CV/CG these are often simply called rotation about the X-, Y-, and Z-axes. The order in which the three rotations are composed (e.g. $R = R_z(\text{yaw})\,R_y(\text{pitch})\,R_x(\text{roll})$) is convention-dependent. Euler-angle representations also suffer from gimbal lock (at certain orientations one rotational degree of freedom is lost); when smooth interpolation or singularity avoidance matters, quaternions or rotation matrices are usually used directly.

Rigid and similarity transformations

Rigid transformation (Euclidean)

Rotation + translation. Preserves shape and size (6 degrees of freedom: 3 rotations + 3 translations).

$$\begin{pmatrix} \mathbf{R} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad \mathbf{R} \in SO(3), \quad \mathbf{t} \in \mathbb{R}^3$$

Similarity transformation

Rigid transform + isotropic scaling. Preserves angles (7 DOF in 3D: 6 rigid + 1 scale).

$$\begin{pmatrix} s\mathbf{R} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad s > 0$$

Affine transformation

Preserves parallelism (12 DOF in 3D: 9 from the linear part $\mathbf{A}$ + 3 from the translation $\mathbf{t}$).

$$\begin{pmatrix} \mathbf{A} & \mathbf{t} \\ \mathbf{0}^T & 1 \end{pmatrix}, \quad \mathbf{A} \in \mathbb{R}^{3 \times 3}$$

Code example (Python)

import numpy as np

def translation_matrix_2d(tx, ty):
    """2D translation matrix"""
    return np.array([
        [1, 0, tx],
        [0, 1, ty],
        [0, 0, 1]
    ])

def rotation_matrix_2d(theta):
    """2D rotation matrix (radians)"""
    c, s = np.cos(theta), np.sin(theta)
    return np.array([
        [c, -s, 0],
        [s,  c, 0],
        [0,  0, 1]
    ])

def scale_matrix_2d(sx, sy):
    """2D scale matrix"""
    return np.array([
        [sx, 0, 0],
        [0, sy, 0],
        [0,  0, 1]
    ])

# Composition: scale -> rotation -> translation
S = scale_matrix_2d(2, 2)
R = rotation_matrix_2d(np.radians(45))
T = translation_matrix_2d(100, 50)
M = T @ R @ S  # applied from right to left

# Transform a point
p = np.array([10, 20, 1])  # homogeneous coordinates
p_transformed = M @ p
print(f"Transformed: ({p_transformed[0]:.1f}, {p_transformed[1]:.1f})")

# Use with OpenCV
import cv2
# img: input image (loaded via cv2.imread)
height, width = img.shape[:2]
# Convert to a 2x3 affine matrix
M_cv = M[:2, :]
img_transformed = cv2.warpAffine(img, M_cv, (width, height))

Summary

  • Homogeneous coordinates let us express transforms, including translation, as matrix products.
  • 2D transforms use $3 \times 3$ matrices; 3D transforms use $4 \times 4$ matrices.
  • Composition of transforms is a matrix product (applied from right to left).
  • A rigid transform is rotation + translation (shape-preserving).
  • A camera's extrinsic parameters are expressed as a rigid transform.