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.
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
Rotation
Scaling
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}))$$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}$$
Pitch (Y-axis)
Roll (X-axis)
Yaw (Z-axis)
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.