Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Preview: SLIC Superpixels

stough, 202-

DIP 10.5

This shows Simple Linear Iterative Clustering at work to show superpixel segmentation of images. We’ll split this up to look at the algorithm in detail. skimage includes numerous segmentation methods, but we’re interested here in understanding the details.

Superpixels are small, compact regions of similar color: an over-segmentation of an image into a few hundred pieces that respect its edges. Working with 300 superpixels instead of 300,000 pixels makes many later steps, like segmentation, object detection, and labeling, much cheaper, while losing little, since pixels within a superpixel are nearly alike anyway.

SLIC (Achanta et al., 2012) is k-means with two twists:

  1. Each pixel is a point in a 5D space: its three color values and its two spatial coordinates. Clustering on color alone (as in our image k-means demo) groups same-colored pixels from anywhere in the image. Adding position makes the clusters spatially compact.

  2. Each cluster center only searches a local window around itself, 2S×2S2S \times 2S pixels where SS is the grid spacing. Standard k-means compares every pixel against every center, O(NK)O(NK) work per iteration. SLIC compares each pixel against only the few centers whose windows overlap it, so the cost is O(N)O(N) no matter how many superpixels we ask for.

Below we build it up step by step.

Parameters

SUPERPIXELS is roughly how many superpixels we want. MAXITER and T control when the iterations stop: after MAXITER iterations, or once the cluster centers move less than T in total.

Helper functions

myfunc returns the most common label in a neighborhood. We’ll use it at the end to clean up stray pixels.

reinitM nudges each initial center to the lowest-gradient pixel in its 3×33 \times 3 neighborhood. A center that happens to land exactly on an edge, or on a noisy pixel, would start with an unrepresentative color. Moving it to the flattest nearby spot avoids that. (The gradient magnitude comes from the Sobel filter.)

convergedYet measures how far all the cluster centers moved during the last iteration, and reports convergence once that total is below T.

Load the image, and choose the grid spacing and the color/space trade-off

With NN pixels and KK superpixels, each superpixel should cover about N/KN/K pixels, so the grid spacing is S=N/KS = \sqrt{N/K} (s in the code).

SLIC’s distance between a pixel and a cluster center combines color distance dcd_c and spatial distance dsd_s (Eq. 10-91 in DIP):

D=dc2+(dsS)2m2D = \sqrt{d_c^2 + \left(\frac{d_s}{S}\right)^2 m^2}

Dividing dsd_s by SS puts distance in units of “grid spacings”. The compactness mm (here cs =m2= m^2) sets the trade-off. Large mm makes spatial distance dominate, giving regular, nearly square superpixels that ignore edges. Small mm lets color dominate, so superpixels follow edges closely but get irregular shapes. Try changing cs and see.

(One difference from the paper: we measure color distance in RGB. Achanta et al. use CIELAB, where Euclidean distance better matches perceived color difference.)

Initialize the cluster centers

We place the centers on a regular grid every s pixels. Each row of M is one center: [R,G,B,row,col][R, G, B, row, col], its color and position. Then reinitM nudges each one off of any edge.

Precompute

D holds, for every pixel, the distance to the best center found so far, and L holds that center’s label. Both get reset as better centers are found. Since every center searches a window of the same size, the spatial distance from the window’s center to each of its pixels is the same every time. We compute it once, as spaceDist.

The main loop: assign, then update

This is k-means, with the local-window twist:

  1. Assign: for each center, look at every pixel in the (2S+1)×(2S+1)(2S+1) \times (2S+1) window around it, and compute the combined distance DD. Wherever that’s smaller than the pixel’s current best distance, claim the pixel for this center. (The commented-out double for-loop is the straightforward version. The numpy version does the same thing for the whole window at once, which is much faster.)

  2. Update: move each center to the mean color and mean position of the pixels it claimed.

  3. Stop when the centers barely move.

iteration 1 normdiff 537.882694.
iteration 2 normdiff 143.432711.
iteration 3 normdiff 65.058386.
iteration 4 normdiff 52.468948.
iteration 5 normdiff 32.172730.
iteration 6 normdiff 19.524376.
iteration 7 normdiff 14.612553.
iteration 8 normdiff 9.864925.

Clean up, and display

After clustering, a few pixels can end up as small islands belonging to a center that is mostly elsewhere. The paper enforces connectivity by relabeling such disconnected fragments. Here we do something simpler: a 5×55 \times 5 mode filter replaces each label with the most common label around it (a non-linear filter, which is why it’s slow).

To display, we paint every pixel with the mean color of its superpixel, and also draw the superpixel borders in white. A pixel is on a border if any of its four direct neighbors has a different label.

<Figure size 800x300 with 3 Axes>

With 300 superpixels, the image is recognizable from the superpixel colors alone, and the borders follow the strong edges, like the outlines of the fish and the stripes on them, while staying fairly compact in flat regions.

Compare with skimage

skimage.segmentation.slic is a fast, polished implementation of the same algorithm, working in Lab color and enforcing connectivity. Its compactness parameter is the mm above.

<Figure size 1000x300 with 3 Axes>

With compactness=30, skimage’s superpixels look much like ours: compact, nearly regular regions that bend to follow the strongest edges, like the outline of the fish. With compactness=10, color dominates. The superpixels wander to follow every color boundary in the busy anemone and coral, and they become very irregular. (skimage also merges tiny fragments, so you get somewhat fewer superpixels than requested.) Which is better depends on what you’ll use the superpixels for.

References
  1. Achanta, R., Shaji, A., Smith, K., Lucchi, A., Fua, P., & Süsstrunk, S. (2012). SLIC Superpixels Compared to State-of-the-Art Superpixel Methods. IEEE Transactions on Pattern Analysis and Machine Intelligence, 34(11), 2274–2282. 10.1109/tpami.2012.120