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)