Affine Transforms

Six numbers rotate, scale, shear and shift an image. Edit them directly and watch what each one controls.

Overview

One matrix for four operations

Rotating, scaling, shearing and translating look like four separate things. They are one thing with different numbers in it — an affine transform, written as a 2×3 matrix:

| a  b  e |
| c  d  f |

A point at (x, y) moves to (ax + by + e, cx + dy + f). The four numbers a, b, c and d handle everything that involves direction — rotation, scale, shear, flip — and e and f slide the result sideways and down.

The defining property is in the name: affine transforms preserve straightness and parallelism. A straight line stays straight, and two parallel lines stay parallel. Anything you can do to a photograph by moving, turning, stretching or skewing it is affine. Anything involving perspective — railway tracks converging — is not, because parallel lines stop being parallel.

Affine Transforms

This module needs JavaScript: the images are computed in the page rather than downloaded.

Worth knowing

An affine transform maps straight lines to straight lines and keeps parallel lines parallel.
The four numbers a, b, c, d do the rotating, scaling and shearing; e and f do the translating.
The determinant ad − bc is how much area scales by. At zero the transform collapses the image to a line.
Implementations iterate over the output and look backwards, because iterating forwards leaves holes.

Affine Transforms

Six numbers that cover every rotation, scale, shear and shift an image can take.

What each number does

Set everything to the identity — a and d at 1, the rest at 0 — and the image is unchanged. Then move one at a time.

a scales horizontally. At 2 the image doubles in width; at 0.5 it halves; at −1 it mirrors left-to-right.

d scales vertically, the same way.

c shears in x. Each row slides sideways in proportion to its distance from the centre, turning a rectangle into a parallelogram. This is the italic transformation.

b shears in y, tilting columns instead of rows.

e and f translate, in pixels, and are the only two that do not interact with the others.

Rotation is not its own control because it does not need one. A rotation by θ is:

a =  cos t    b = -sin t
c =  sin t    d =  cos t

Set a and d to 0.87 and c to 0.5 with b at −0.5 and the image turns by thirty degrees. Rotation is a particular combination of scale and shear, which is the sort of fact the matrix makes obvious and four separate functions hide.

The determinant

The readout under the visualisation shows ad − bc, the determinant. It has a direct meaning: it is the factor by which area is multiplied.

A pure rotation has determinant 1, because rotating does not change area. Doubling both scales gives 4. A negative determinant means the image has been flipped — orientation reversed.

At determinant 0 the transform is not invertible, and geometrically it has collapsed the plane onto a line. Set a and c to the same value with b and d matching and the image degenerates. Nothing can undo that, because the information about position along the lost direction is gone.

Why implementations work backwards

The obvious way to apply a transform is to loop over input pixels, compute where each lands, and write it there. This produces a broken image.

When the transform enlarges, adjacent input pixels land more than one pixel apart in the output, leaving gaps that nothing ever writes to — a lattice of holes. When it shrinks, several inputs land on the same output and fight over it.

Real implementations invert the problem. Loop over every output pixel, apply the *inverse* transform to find where it came from in the input, and sample there. Every output pixel gets written exactly once, so there are no holes, and the sampling step is an ordinary interpolation problem — nearest neighbour or bilinear, with the same trade-offs as [resizing](resizing_and_interpolation.html).

This is why the code above computes the inverse rather than the forward map, and why an affine transform needs an interpolation choice at all.

Where it shows up

Data augmentation. Small random rotations, scales and shears applied to training images teach a network that a cat rotated by ten degrees is still a cat. It is the cheapest regularisation there is, and it is affine.

Image registration. Aligning two photographs of the same scene means finding the affine transform that best maps one onto the other.

Document scanning. Straightening a page photographed at an angle is affine if the camera was square to the page and projective if it was not, which is why scanning apps ask you to mark the corners.

Where it goes wrong

Expecting to correct perspective. Affine cannot. A photograph taken from an angle needs a projective (homography) transform, which has eight parameters and does not preserve parallelism.

Composing in the wrong order. Matrix multiplication does not commute. Rotate-then-translate and translate-then-rotate give different results, and which one you meant is usually clear only after seeing the wrong one.

Rotating about the origin by accident. The formulas rotate about (0, 0), which is a corner. Rotating about the centre means translating the centre to the origin, rotating, and translating back — three matrices multiplied together.

Losing the corners. A rotated rectangle does not fit in the original frame. Either accept the clipping or compute the bounding box of the transformed corners and enlarge the canvas first.

Check yourself

0 of 3

Answer without scrolling back up.

  1. What does the determinant ad - bc of an affine transform tell you?

  2. Why do implementations iterate over output pixels and apply the inverse transform?

  3. Which of these is NOT an affine transform?

Cheat sheet

Affine Transforms

Rotating, scaling, shearing and translating look like four separate things. They are one thing with different numbers in it — an affine transform, written as a 2×3 matrix:

COMPUTER VISION · vizlearn.in/computer_vision/affine_transforms.html

About the author

Ashish Jangra builds and maintains VizLearn. Every module here is written and the visualisation behind it hand-built, so the numbers in a readout come from the same code that draws the picture. Corrections are genuinely welcome and get priority over everything else — if a page states something wrong, or an animation misrepresents what the algorithm does, get in touch.