Intermediate
Image Processing with OpenCV
Master the fundamentals of image manipulation: reading, writing, transforming, filtering, and enhancing images using OpenCV's powerful processing pipeline.
Reading and Writing Images
Python — Basic I/O
import cv2
import numpy as np
# Read image (BGR format by default)
img = cv2.imread("photo.jpg")
gray = cv2.imread("photo.jpg", cv2.IMREAD_GRAYSCALE)
# Image properties
print(f"Shape: {img.shape}") # (height, width, channels)
print(f"Dtype: {img.dtype}") # uint8
print(f"Size: {img.size}") # total pixels
# Write image
cv2.imwrite("output.png", img)
cv2.imwrite("output.jpg", img, [cv2.IMWRITE_JPEG_QUALITY, 95])
Color Space Conversions
OpenCV supports over 150 color space conversions. The most common ones:
Python — Color spaces
# BGR to RGB (for matplotlib/PIL compatibility)
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# BGR to Grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# BGR to HSV (great for color-based detection)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# BGR to LAB (perceptual color space)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
Image Transformations
Python — Resize, rotate, crop
# Resize
resized = cv2.resize(img, (640, 480))
scaled = cv2.resize(img, None, fx=0.5, fy=0.5)
# Rotate
h, w = img.shape[:2]
center = (w // 2, h // 2)
matrix = cv2.getRotationMatrix2D(center, 45, 1.0)
rotated = cv2.warpAffine(img, matrix, (w, h))
# Crop (just NumPy slicing)
cropped = img[100:400, 200:500]
# Flip
flipped_h = cv2.flip(img, 1) # horizontal
flipped_v = cv2.flip(img, 0) # vertical
Filtering and Blurring
Python — Filters
# Gaussian blur (noise reduction)
blurred = cv2.GaussianBlur(img, (5, 5), 0)
# Median blur (salt-and-pepper noise)
median = cv2.medianBlur(img, 5)
# Bilateral filter (edge-preserving smoothing)
bilateral = cv2.bilateralFilter(img, 9, 75, 75)
# Sharpening with custom kernel
kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]])
sharpened = cv2.filter2D(img, -1, kernel)
Thresholding
Python — Thresholding techniques
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Simple threshold
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# Otsu's automatic threshold
_, otsu = cv2.threshold(gray, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Adaptive threshold (handles uneven lighting)
adaptive = cv2.adaptiveThreshold(gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
Edge Detection
Python — Edge detection
# Canny edge detection
edges = cv2.Canny(gray, 50, 150)
# Sobel gradients
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
sobel = cv2.magnitude(sobel_x, sobel_y)
# Laplacian
laplacian = cv2.Laplacian(gray, cv2.CV_64F)
Pro tip: Always apply Gaussian blur before Canny edge detection to reduce noise. The two threshold values in Canny control sensitivity — start with a 1:3 ratio (e.g., 50:150) and adjust from there.
Drawing on Images
Python — Drawing primitives
canvas = np.zeros((400, 600, 3), dtype=np.uint8)
# Line, rectangle, circle, text
cv2.line(canvas, (0, 0), (600, 400), (0, 255, 0), 2)
cv2.rectangle(canvas, (50, 50), (200, 150), (255, 0, 0), 2)
cv2.circle(canvas, (300, 200), 80, (0, 0, 255), -1) # -1 = filled
cv2.putText(canvas, "OpenCV", (350, 350),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
Lilly Tech Systems