Learning/IVP/Session 07
Session 07⚖️

Thresholding & Segmentation

Separating foreground from background using global and adaptive thresholding, and Otsu's method.


Learning Objectives

  • Apply manual global thresholding
  • Use Otsu's automatic threshold selection
  • Apply adaptive local thresholding for uneven lighting
  • Label connected regions in binary images

Global Thresholding

Global thresholding applies a single threshold T to the whole image. If pixel > T → white (foreground), else → black (background). Manual selection requires domain knowledge. cv2.THRESH_BINARY is the basic mode.

Ex7_1a — Manual global thresholdPython
import cv2

img = cv2.imread('coins.jpg', cv2.IMREAD_GRAYSCALE)

# Manual threshold at 127
_, binary_manual = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

Otsu's Automatic Thresholding

Otsu's method automatically finds the threshold T that minimizes within-class variance (equivalently, maximizes between-class variance). Pass cv2.THRESH_OTSU flag and set threshold to 0 — OpenCV computes the optimal T.

Ex7_1b — Otsu automatic thresholdPython
# Otsu's method - threshold value is computed automatically
T_otsu, binary_otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(f'Otsu threshold: {T_otsu}')

Adaptive Local Thresholding

When lighting varies across the image, a single global threshold fails. Adaptive thresholding computes a different threshold for each pixel based on a local neighborhood. Two methods: mean of neighborhood or Gaussian-weighted mean.

Ex7_2 — Adaptive thresholdingPython
# Adaptive mean threshold (block size 11, constant C=2)
adaptive_mean = cv2.adaptiveThreshold(
    img, 255,
    cv2.ADAPTIVE_THRESH_MEAN_C,
    cv2.THRESH_BINARY, 11, 2
)

# Adaptive Gaussian threshold
adaptive_gauss = cv2.adaptiveThreshold(
    img, 255,
    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
    cv2.THRESH_BINARY, 11, 2
)

Region Labeling

After binarization, connected-component labeling assigns a unique integer label to each connected region (blob). cv2.connectedComponentsWithStats() returns the label map and statistics (area, bounding box) for each region.

Ex7_3 — Connected component labelingPython
import cv2
import numpy as np

img = cv2.imread('objects.jpg', cv2.IMREAD_GRAYSCALE)
_, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary)
print(f'Found {num_labels - 1} regions (excluding background)')