Transforming Images
Resizing, rotating, and warping.
Cameras aren't always straight. A crate label is photographed at an angle. A farm worker's phone is held sideways. Before we can read or measure anything, we often need to straighten the picture. These transforms are the everyday tools of vision work.

- Cameras aren't always straight
- Labels at odd angles
- Straighten first, then read
Resize, rotate, and warp
Three transforms. Resize changes the size. Rotation uses a small matrix. And the third is the clever one. Perspective warping takes any four corners, and stretches them into a flat rectangle, as if you were looking straight at it. Run it. Look at the third image. That's how scanner apps turn a tilted photo of a document into a flat page.
import cv2
import numpy as np
import matplotlib.pyplot as plt
from skimage import data
image = data.chelsea()
h, w = image.shape[:2]
small = cv2.resize(image, (w // 3, h // 3), interpolation=cv2.INTER_AREA)
turn = cv2.getRotationMatrix2D((w / 2, h / 2), 25, 1.0)
rotated = cv2.warpAffine(image, turn, (w, h))
src = np.float32([[60, 40], [430, 80], [420, 280], [40, 260]])
dst = np.float32([[0, 0], [300, 0], [300, 200], [0, 200]])
straight = cv2.warpPerspective(image, cv2.getPerspectiveTransform(src, dst), (300, 200))
fig, ax = plt.subplots(1, 3, figsize=(10, 3))
for a, im, n in zip(ax, [small, rotated, straight], ["Resized", "Rotated", "Perspective"]):
a.imshow(im); a.set_title(n); a.axis("off")
plt.tight_layout(); plt.savefig("transforms.png", dpi=110)
print("Sizes:", image.shape, small.shape, straight.shape)Sizes: (300, 451, 3) (100, 150, 3) (200, 300, 3)
Fixing contrast
The barn at Orchard Vision is dark, and photos look dull. Histogram equalisation stretches the brightness across the whole range. CLAHE does this region by region, with a limit, so that it doesn't blow out the noise. Run it. The dull photo becomes clear. CLAHE is widely used for medical scans, and for low light.
import cv2
import matplotlib.pyplot as plt
from skimage import data
gray = (data.camera() * 0.35 + 40).astype("uint8")
plain = cv2.equalizeHist(gray)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)).apply(gray)
fig, ax = plt.subplots(1, 3, figsize=(10, 3))
for a, im, n in zip(ax, [gray, plain, clahe], ["Dull photo", "Equalised", "CLAHE"]):
a.imshow(im, cmap="gray", vmin=0, vmax=255); a.set_title(n); a.axis("off")
plt.tight_layout(); plt.savefig("contrast.png", dpi=110)
print("Brightness range before:", gray.min(), gray.max())
print("After CLAHE: ", clahe.min(), clahe.max())Brightness range before: 40 129 After CLAHE: 23 199
Summary
Geometry straightens images, and contrast tools reveal detail. Now, let's find things, starting with the simplest way there is. Look for an exact copy.
Key takeaways- Warp four corners to flatten
- Equalise for contrast
- CLAHE works region by region