Title: Segmentation: A SLIC Superpixel Tutorial using Python - PyImageSearch

URL Source: https://pyimagesearch.com/2014/07/28/a-slic-superpixel-tutorial-using-python/

Published Time: 2014-07-28T14:00:15+00:00

Markdown Content:
Have you ever had a horrible case of eyelid twitching? One where your eyelid _just won’t stop spazzing out_, no matter what you do?

[![Image 1](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20519'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/07/slic_100_segments.jpg)

That’s currently what’s going on with me — and it’s been going on _for over two weeks_. As you can imagine, I’m not exactly happy.

However, to combat this persistent, often distracting nuisance, I’ve started sleeping more regularly, drinking substantially less caffeine (I was only drinking two cups of coffee a day to begin with), and consuming next to no alcohol. Which is a real challenge when you enjoy a frothy beer as much as I do.

More sleep has certainly helped. And I don’t miss the occasional beer.

But man, these caffeine headaches **_are the worst_**.

Luckily, I woke up this morning to an email that practically cured me of my caffeine free woes and interminable eyelid twitching.

Opening my inbox, I found an excellent question from dedicated PyImageSearch reader Sriharsha Annamaneni, who wrote in and asked:

> Hi Adrian,
> 
> In one of [Jitendra Malik’s YouTube videos](https://www.youtube.com/watch?v=Mqg6eorYRIQ), he explains superpixels. I did not understand it completely. Can you explain it on your website?
> 
> Thank you,
> 
> Sriharsha Annamaneni

Great question Sriharsha. I’d be happy to discuss superpixels, I’m sure a ton of other PyImageSearch readers would be interested too.

But before we dive into some code, let’s discuss what exactly a superpixel is and why it has important applications in the computer vision domain.

![Image 2](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20128%20128'%3E%3C/svg%3E)

#### Looking for the source code to this post?

[Jump Right To The Downloads Section](#download-the-code)

**OpenCV and Python versions:**  
This example will run on **Python 2.7/Python 3.4+** and **OpenCV 2.4.X/OpenCV 3.0+**.

So, What’s a Superpixel?
------------------------

Take a second, clear your mind, and consider how we represent images.

Images are represented as a grid of pixels, in either single or multiple channels.

We take these _M x N_ pixel grids and then apply algorithms to them, such as face detection and recognition, template matching, and even deep learning applied directly to the raw pixel intensities.

The problem is that our pixel grid is **_by no means_** a natural representation of an image.

For example, consider the image below:

[![Image 3: Figure 1: If I were to take the single pixel pointed to by the red arrow (left) and show it to you (right), would you be able to tell me anything about the image? Anything Descriptive? Of semantic value?](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20361'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/07/slic_example_pixel.jpg)

**Figure 1:** If I were to take the _single pixel_ pointed to by the red arrow _(left)_ and show it to you on the _right_ at an obviously zoomed-in scale, would you be able to tell me anything about the image based solely on that pixel? Anything descriptive? Or of semantic value?

If I were to take a single pixel from the image on the _left_ (highlighted by the red arrow) and then showed it to you on the _right_, could you reasonably tell me that (1) that pixel came from a Velociraptor and (2) that single pixel actually holds some sort of semantic meaning?

Unless you really, _really_ want to play devils advocate, the answer is a resounding no — a single pixel, standing alone by itself, is not a natural representation of an image.

Taken as a whole, this grouping of pixels as a pixel grid is simply an artifact of an image — part of the process of capturing and creating digital images.

That leads us to superpixels.

Intuitively, it would make more sense to explore not only perceptual, but semantic meanings of an image formed by locally grouping pixels as well.

When we perform this type of local grouping of pixels on our pixel grid, we arrive at **_superpixels_**.

These superpixels carry more perceptual and semantic meaning than their simple pixel grid counterparts.

Benefits of Superpixels
-----------------------

To summarize the work of [Dr. Xiaofeng Ren](http://ttic.uchicago.edu/~xren/research/superpixel/), we can see that a mapping from pixel grids to superpixels would (ideally) hold the desirable properties of:

1.  **Computational efficiency:** While it may be (somewhat) computationally expensive to compute the actual superpixel groupings, it allows us to reduce the complexity of the images themselves from hundreds of thousands of pixels to only a few hundred superpixels. Each of these superpixels will then contain some sort of perceptual, and ideally, semantic value.
2.  **Perceptual meaningfulness:** Instead of only examining a single pixel in a pixel grid, which caries very little perceptual meaning, pixels that belong to a superpixel group share some sort of commonality, such as similar color or texture distribution.
3.  **Oversegmentation:** Most superpixel algorithms _oversegment_ the image. This means that most of important boundaries in the image are found; however, at the expense of generating many insignificant boundaries. While this may sound like a problem or a deterrent to using super pixels, it’s actually a positive — the end product of this oversegmentation is that that very little (or no) pixels are lost from the pixel grid to superpixel mapping.
4.  **Graphs over superpixels:** Dr. Ren refers to this concept as “representationally efficient”. To make this more concrete, imagine constructing a graph over a _50,000 x 50,000_ pixel grid, where each pixel represents a node in the graph — that leads to very large representation. However, suppose we instead applied superpixels to the pixel grid space, leaving us with a (arbitrary) 200 superpixels. In this representation, constructing a graph over the 200 superpixels is substantially more efficient.

Example: Simple Linear Iterative Clustering (SLIC)
--------------------------------------------------

As always, a PyImageSearch blog post wouldn’t be complete without an example and some code.

Ready?

Open up your favorite editor, create `slic.py` , and let’s get coding:

\# import the necessary packages
from skimage.segmentation import slic
from skimage.segmentation import mark\_boundaries
from skimage.util import img\_as\_float
from skimage import io
import matplotlib.pyplot as plt
import argparse

# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add\_argument("-i", "--image", required = True, help = "Path to the image")
args = vars(ap.parse\_args())

# load the image and convert it to a floating point data type
image = img\_as\_float(io.imread(args\["image"\]))

# loop over the number of segments
for numSegments in (100, 200, 300):
	# apply SLIC and extract (approximately) the supplied number
	# of segments
	segments = slic(image, n\_segments = numSegments, sigma = 5)

	# show the output of SLIC
	fig = plt.figure("Superpixels -- %d segments" % (numSegments))
	ax = fig.add\_subplot(1, 1, 1)
	ax.imshow(mark\_boundaries(image, segments))
	plt.axis("off")

# show the plots
plt.show()

On **Lines 2-7** we import the packages we’ll be using for this example. To perform the SLIC superpixel segmentation, we will be using the [sckit-image implementation](http://scikit-image.org/docs/dev/api/skimage.segmentation.html#skimage.segmentation.slic), which we import on **Line 2**. To draw the actual superpixel segmentations, scikit-image provides us with a `mark_boundaries` function which we import on **Line 3**.

From there, we import a utility function, `img_as_float` on **Line 4**, which as the name suggests, converts an image from an unsigned 8-bit integer, to a floating point data with, with all pixel values called to the range _\[0, 1\]_.

**Line 5** imports the `io` sub-package of scikit-image which is used for loading and saving images.

We’ll also make use of matplotlib to plot our results and `argparse` to parse our command line arguments.

**Lines 10-12** handle parsing our command line arguments. We need only a single switch, `--image` , which is the path to where our image resides on disk.

We then load this image and convert it from an unsigned 8-bit integer to a floating point data type on **Line 15**.

Now the interesting stuff happens.

We start looping over our number of superpixel segments on **Line 18**. In this case, we’ll be examining three increasing sizes of segments: 100, 200, and 300, respectively.

We perform the SLIC superpixel segmentation on **Line 21**. The `slic` function takes only a single _required_ parameter, which is the image we want to perform superpixel segmentation on.

However, the `slic` function also provides many optional parameters, which I’ll only cover a sample of here.

The first is the is the `n_segments` argument which defines how many superpixel segments we want to generate. This value defaults to 100 segments.

We then supply `sigma` , which is the smoothing Gaussian kernel applied prior to segmentation.

Other optional parameters can be utilized in the function, such as `max_iter` , which the maximum number of iterations for k-means, `compactness` , which balances the color-space proximity with image space-proximity, and `convert2lab` which determines whether the input image should be converted to the L\*a\*b\* color space prior to forming superpixels (in nearly **_all_** cases, having `convert2lab` set to `True` is a good idea).

Now that we have our segments, we display them using matplotlib in **Lines 24-27**.

In order to draw the segmentations, we make use of the `mark_boundaries` function which simply takes our original image and overlays our superpixel segments.

Finally, our results are displayed on **Line 30**.

Now that our code is done, let’s see what our results look like.

Fire up a shell and execute the following command:

$ python superpixel.py --image raptors.png

If all goes well, you should see the following image:

[![Image 4: Applying SLIC superpixel segmentation to generate 100 superpixels using Python.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20519'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/07/slic_100_segments.jpg)

**Figure 2:** Applying SLIC superpixel segmentation to generate 100 superpixels using Python.

In this image, we have found (approximately) 100 superpixel segmentations. Notice how locally similar regions of the image, such as the scales of the Velociraptor and the shrubbery are grouped in similar superpixels.

Now, let’s increase to 200 superpixel segments:

[![Image 5: Applying SLIC superpixel segmentation to generate 200 superpixels using Python.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20519'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/07/slic_200_segments.jpg)

**Figure 3:** Applying SLIC superpixel segmentation to generate 200 superpixels using Python.

Same story here — local regions with similar color and texture distributions are part of the same superpixel group.

Finally, let’s generate a very dramatic oversegmentation of the image using 300 super pixels:

[![Image 6: Applying SLIC superpixel segmentation to generate 300 superpixels using Python.](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20600%20519'%3E%3C/svg%3E)](https://pyimagesearch.com/wp-content/uploads/2014/07/slic_300_segments.jpg)

**Figure 4:** Applying SLIC superpixel segmentation to generate 300 superpixels using Python.

Notice how as the number of segments increases, the segments also become more rectangular and grid like. This is not a coincidence, and it can be further controlled by the optional `compactness` parameter of `slic` .

### What's next? We recommend [PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend).

**Course information:**  
84 total classes • 114+ hours of on-demand code walkthrough videos • Last updated: February 2024  
★★★★★ 4.84 (128 Ratings) • 16,000+ Students Enrolled

**I strongly believe that if you had the right teacher you could _master_ computer vision and deep learning.**

Do you think learning computer vision and deep learning has to be time-consuming, overwhelming, and complicated? Or has to involve complex mathematics and equations? Or requires a degree in computer science?

That’s _not_ the case.

All you need to master computer vision and deep learning is for someone to explain things to you in _simple, intuitive_ terms. _And that’s exactly what I do_. My mission is to change education and how complex Artificial Intelligence topics are taught.

If you're serious about learning computer vision, your next stop should be PyImageSearch University, the most comprehensive computer vision, deep learning, and OpenCV course online today. Here you’ll learn how to _successfully_ and _confidently_ apply computer vision to your work, research, and projects. Join me in computer vision mastery.

**Inside PyImageSearch University you'll find:**

*   ✓ **84 courses** on essential computer vision, deep learning, and OpenCV topics
*   ✓ **84 Certificates** of Completion
*   ✓ **114+ hours** of on-demand video
*   ✓ **Brand new courses released _regularly_**, ensuring you can keep up with state-of-the-art techniques
*   ✓ **Pre-configured Jupyter Notebooks in Google Colab**
*   ✓ Run all code examples in your web browser — works on Windows, macOS, and Linux (no dev environment configuration required!)
*   ✓ Access to **centralized code repos for _all_ 536+ tutorials** on PyImageSearch
*   ✓ **Easy one-click downloads** for code, datasets, pre-trained models, etc.
*   ✓ **Access** on mobile, laptop, desktop, etc.

[Click here to join PyImageSearch University](https://pyimagesearch.com/pyimagesearch-university/?utm_source=blogPost&utm_medium=bottomBanner&utm_campaign=What%27s%20next%3F%20I%20recommend)

Summary
-------

In this blog post I explained what superpixel segmentation is and how it has many benefits in the computer vision world.

For example, working with superpixels instead of the standard pixel grid space yields us **computational efficiency**, **perceptual meaningfulness**, **oversegmentation**, and efficient **graph representations across regions of the image**.

Finally, I showed you how to utilize the Simple Linear Iterative Clustering (SLIC) algorithm to apply superpixel segmentation to your own images.

This certainly won’t be the last time we discuss superpixels on this blog, so look forward to more posts in the future!

![Image 7](data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20410%20567'%3E%3C/svg%3E)

#### Download the Source Code and FREE 17-page Resource Guide

Enter your email address below to get a .zip of the code and a **FREE 17-page Resource Guide on Computer Vision, OpenCV, and Deep Learning.** Inside you'll find my hand-picked tutorials, books, courses, and libraries to help you master CV and DL!