Watershed treats the gradient image as a topographic landscape and floods it from marker seeds, drawing boundaries where rising water from different basins would meet.
The watershed algorithm borrows its intuition from hydrology. Imagine pouring water onto a mountain range: it flows downhill, collects in valleys, and two streams separated by a ridge belong to different drainage basins. In image processing, the gradient magnitude image |∇I| plays the role of the terrain — high gradient = ridge (edge), low gradient = valley (homogeneous region). The algorithm floods this landscape from local minima upward. Every pixel eventually belongs to the basin whose seed reached it first.
Key mapping: pixel intensity in the gradient image → elevation. Local minimum → basin seed (valley bottom). High gradient → ridge (likely an object boundary). Watershed line → the boundary drawn where adjacent basins meet — this becomes the segmentation contour.
Naive watershed floods from every local minimum — which causes extreme over-segmentation (see Section 3). The practical version is marker-controlled watershed: you provide seeds (markers) for each object and one background marker, then flood only from those seeds. This gives you direct control over the number of output regions.
Algorithm steps: (1) Compute gradient magnitude |∇I|. (2) Place foreground markers inside each object of interest (e.g., brightest points from distance transform). (3) Place a background marker in background regions. (4) Run priority-queue flooding: pixels are processed in order of gradient height, lowest first. Each pixel inherits the label of the lowest-gradient neighbour already labelled. (5) When a pixel would receive two different labels simultaneously, mark it as a watershed boundary. (6) Output: label map where each pixel is assigned a region ID or boundary.
Markers are typically generated automatically: for cell segmentation, the distance transform of a binary foreground mask is computed first — local maxima of the distance transform correspond to object centres (furthest from any background pixel), making excellent seeds. For more general cases, morphological erosion or manual annotation supplies the markers.
The classic failure mode of naive watershed is over-segmentation: even a slightly noisy gradient image has hundreds of spurious local minima, each generating its own basin. The result looks like a shattered mosaic rather than a clean partition. Three standard remedies exist:
Watershed excels wherever objects touch or overlap, making boundary detection alone insufficient. The classic application is cell counting in microscopy: cells stain as bright blobs that often touch; watershed separates them using the distance-transform-seeded approach. Other applications include geology (watershed of elevation DEMs), document analysis (separating touching printed characters), and industrial inspection (segmenting overlapping components on a conveyor).
cv2.watershed(img, markers) modifies the markers array in place. Boundaries are set to -1. Input must be 8UC3 (BGR image), markers must be 32-bit signed integers with positive region IDs and 0 for unknown pixels.skimage.segmentation.watershed(gradient, markers) accepts grayscale gradient images. The compactness parameter mixes gradient and Euclidean distance, producing more regular-shaped regions (useful for superpixel generation).Say the answer out loud before revealing — recalling is what makes it stick. ➜ Next: Sliding Window Detection
What does the gradient magnitude image represent in watershed?
Why does naive watershed over-segment images?
How does the distance transform help with cell segmentation?
What is the key difference between watershed and mean shift segmentation?