Nearly every model and pipeline needs images at a fixed size and orientation, and the wrong interpolation costs quality.
Cropping needs no cv2 call: slice the array, img[y1:y2, x1:x2]. The result is a view, so drawing on it changes the original; add .copy() for an independent crop.
cv2.resize(img, dsize, fx=..., fy=..., interpolation=...) scales an image. Either pass an explicit size as `(width, height)` or pass dsize=None with scale factors fx, fy. To keep the aspect ratio, compute one side from the other.
The interpolation choice matters:
cv2.INTER_AREA: best for shrinking; averages pixels and avoids moirecv2.INTER_LINEAR(default): fast and fine for moderate enlargingcv2.INTER_CUBICorINTER_LANCZOS4: sharper enlargements, slowercv2.INTER_NEAREST: no blending; use it for label masks and segmentation maps, where averaging would invent classes that don't exist
cv2.flip(img, code) mirrors: 1 horizontally, 0 vertically, -1 both. Horizontal flips are a common data augmentation.
cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) (also ROTATE_180, ROTATE_90_COUNTERCLOCKWISE) rotates by right angles exactly, swapping width and height for 90-degree turns. Arbitrary angles need an affine warp, covered later.
Many models also expect letterboxing: resize to fit inside the target while keeping aspect ratio, then pad the rest with cv2.copyMakeBorder.
Example
import cv2
import numpy as np
img = np.random.default_rng(0).integers(0, 256, (480, 640, 3), dtype=np.uint8)
crop = img[100:300, 200:500] # rows y, then cols x
print(crop.shape) # (200, 300, 3)
small = cv2.resize(img, (320, 240), interpolation=cv2.INTER_AREA) # (w, h)!
print(small.shape) # (240, 320, 3)
half = cv2.resize(img, None, fx=0.5, fy=0.5)
print(half.shape) # (240, 320, 3)
target_w = 200 # keep aspect ratio
h, w = img.shape[:2]
fit = cv2.resize(img, (target_w, round(h * target_w / w)), interpolation=cv2.INTER_AREA)
print(fit.shape) # (150, 200, 3)
mirrored = cv2.flip(img, 1)
print((mirrored[:, 0] == img[:, -1]).all()) # True
print(cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE).shape) # (640, 480, 3)Remember
- Crop by slicing
img[y1:y2, x1:x2](a view) cv2.resizetakes(width, height)or scale factors- INTER_AREA to shrink, LINEAR/CUBIC to enlarge, NEAREST for masks
cv2.flipandcv2.rotatehandle mirrors and right-angle turns
Watch out for
- Resizing a segmentation mask with the default linear interpolation, which creates blended label values.