Crop, Flip & Rotate Images
Geometric image edits with pure NumPy: cropping with slicing, flipping with [::-1] or np.flip, and rotating with np.rot90.
Watch the lesson
1 video on CodeWithMunnaX
Cropping a player out of a team photo, mirroring a selfie, turning a sideways phone picture upright — these feel like "image editing", but in NumPy they are just slicing and reordering axes. No pixel values change; only their positions do.
Definition
Cropping selects a rectangular sub-region of an image using slicing:
img[top:bottom, left:right].
Flipping reverses the order of pixels along an axis: along axis 0 (rows) it mirrors top ↔ bottom, along axis 1 (columns) it mirrors left ↔ right.
Rotating by 90° turns the grid:
np.rot90rotates anticlockwise by default; rows become columns.
- Slicing returns a view — a crop or flip made with
[...]shares memory with the original (no copy, very fast). Changing it changes the original. [::-1]— the step-1walks an axis backwards.- Axis 0 = height, axis 1 = width, axis 2 = channels — flip only axes 0/1 for geometric changes.
Syntax
python
img[r1:r2, c1:c2] # crop (rows r1..r2-1, cols c1..c2-1)
img[::-1] # flip vertically (same as np.flipud)
img[:, ::-1] # flip horizontally (same as np.fliplr)
np.flip(m, axis=None)
np.rot90(m, k=1, axes=(0, 1))| Function | Parameter | Meaning | Default |
|---|---|---|---|
np.flip | m | Array to flip | — required |
np.flip | axis | Axis (or tuple of axes) to reverse | None → all axes |
np.rot90 | m | Array to rotate (≥ 2D) | — required |
np.rot90 | k | Number of 90° turns; positive = anticlockwise, negative = clockwise | 1 |
np.rot90 | axes | The plane to rotate in | (0, 1) → height/width, channels untouched |
np.flipud / np.fliplr | m | Shortcut for flip on axis 0 / axis 1 | — |
Example — cropping with slicing
python
import numpy as np
img = np.arange(1, 21, dtype=np.uint8).reshape(4, 5)
print(img)
print("crop rows 1-2, cols 1-3:")
print(img[1:3, 1:4])text
[[ 1 2 3 4 5]
[ 6 7 8 9 10]
[11 12 13 14 15]
[16 17 18 19 20]]
crop rows 1-2, cols 1-3:
[[ 7 8 9]
[12 13 14]]How it works: like every Python slice, the stop index is excluded: 1:3 = rows 1 and 2, 1:4 = columns 1, 2, 3. For a colour image the same slice keeps all channels automatically: rgb[1:3, 1:4] → shape (2, 3, 3). A centre crop of size h×w is img[(H-h)//2 : (H-h)//2 + h, (W-w)//2 : (W-w)//2 + w].
Example — flipping
python
img = np.arange(1, 7).reshape(2, 3)
print(img)
print("flip up-down, img[::-1]")
print(img[::-1])
print("flip left-right, img[:, ::-1]")
print(img[:, ::-1])
print("np.flip(img) - both axes")
print(np.flip(img))text
[[1 2 3]
[4 5 6]]
flip up-down, img[::-1]
[[4 5 6]
[1 2 3]]
flip left-right, img[:, ::-1]
[[3 2 1]
[6 5 4]]
np.flip(img) - both axes
[[6 5 4]
[3 2 1]]img[:, ::-1] is the "selfie mirror". np.flip with no axis reverses every axis — which equals a 180° rotation for a 2D image.
Example — rotating with np.rot90
python
img = np.arange(1, 7).reshape(2, 3)
print("np.rot90(img) - 90 deg anticlockwise")
print(np.rot90(img))
print("np.rot90(img, k=-1) - 90 deg clockwise")
print(np.rot90(img, k=-1))
print("np.rot90(img, k=2) - 180 deg")
print(np.rot90(img, k=2))text
np.rot90(img) - 90 deg anticlockwise
[[3 6]
[2 5]
[1 4]]
np.rot90(img, k=-1) - 90 deg clockwise
[[4 1]
[5 2]
[6 3]]
np.rot90(img, k=2) - 180 deg
[[6 5 4]
[3 2 1]]How it works: a (2, 3) image becomes (3, 2) after a 90° turn — height and width swap. Rotating anticlockwise puts the last column (3 6) on top. For a colour image np.rot90(rgb) rotates in the height/width plane and leaves the 3 channels alone.
Example — flipping a colour image vs reversing channels
python
rgb = np.zeros((2, 2, 3), dtype=np.uint8)
rgb[:, 0] = [255, 0, 0] # left column red
rgb[:, 1] = [0, 255, 0] # right column green
mirrored = rgb[:, ::-1] # flip width only
print(mirrored[0])
bgr = rgb[..., ::-1] # reverse the channel axis: RGB -> BGR
print(bgr[0])text
[[ 0 255 0]
[255 0 0]]
[[ 0 0 255]
[ 0 255 0]]Flipping axis 1 swapped the positions (green is now on the left). Reversing axis 2 instead swapped the colour order inside each pixel — red [255, 0, 0] became [0, 0, 255]. That is exactly how you convert between RGB (Pillow, matplotlib) and BGR (OpenCV).
Comparison — geometric operations
| Goal | Code | Shape (H, W) → | View or copy? |
|---|---|---|---|
| Crop | img[r1:r2, c1:c2] | (r2-r1, c2-c1) | view |
| Flip vertical | img[::-1] / np.flipud(img) | same | view |
| Flip horizontal | img[:, ::-1] / np.fliplr(img) | same | view |
| Rotate 90° anticlockwise | np.rot90(img) | (W, H) | view |
| Rotate 90° clockwise | np.rot90(img, k=-1) | (W, H) | view |
| Rotate 180° | np.rot90(img, 2) / np.flip(img) (2D) | same | view |
| Transpose (mirror on diagonal) | img.T (2D) / img.transpose(1, 0, 2) (RGB) | (W, H) | view |
| RGB ↔ BGR | img[..., ::-1] | same | view |
Common mistakes
- ❌ Editing a crop and being surprised the original changed (
crop = img[1:3, 1:4]; crop[0, 0] = 99changesimg[1, 1]). ✅crop = img[1:3, 1:4].copy()when you need an independent piece. - ❌
np.flip(rgb)on a colour image — with no axis it also reverses the channels. ✅np.flip(rgb, axis=1). - ❌ Using
.Ton an RGB image — it reverses all axes giving shape(3, W, H). ✅rgb.transpose(1, 0, 2). - ❌ Expecting
np.rot90to turn clockwise. ✅ Default is anticlockwise; usek=-1for clockwise.
Interview tip
Q: How do you mirror an image horizontally in NumPy, and does it copy the data?
A: img[:, ::-1] (or np.fliplr(img)). It returns a view with a negative stride, so no pixel data is copied — it is instant even for huge images.
Key points to remember
- Crop with slicing: img[top:bottom, left:right] — the stop index is excluded.
- img[::-1] flips top-bottom, img[:, ::-1] flips left-right (selfie mirror).
- np.flip(m, axis) reverses the given axis; with no axis it reverses all axes.
- np.rot90(m, k) rotates anticlockwise k times; k=-1 is clockwise; H and W swap for 90°.
- img[..., ::-1] reverses the channel order — RGB ↔ BGR conversion.
- Slices, flips and rotations return views: copy() before editing if the original must stay unchanged.
Try it yourself
Crop, flip and rotate a tiny image
Draw an arrow and rotate it
View vs copy when cropping
Practice: flip a colour image
Revision Flashcards
Tap a card to flip it and see the answer.
