Tragic. Heartbreaking. Unbearable.
These are the three words that I would use to describe my past week.
About a week ago, a close childhood friend of mine passed away in a tragic car accident.
I went to elementary school and middle school with him. We spent our summers skateboarding on my driveway and the winters snowboarding and sledding in my backyard.
Since last week Iāve spent my time traveling and attending his viewing and service. Every moment has been utterly agonizing. I find it extremely hard to focus, my mind always wandering back to memories now over a decade old.
To be honest, itās a wonder I am even writing this blog post at all.
But if there is anything I believe in, itās that life should be celebrated. And there is no better form of celebration than the nostalgic memories of a loved one.
Back in middle school, him and I used to go through CCS Catalogs (yes, actual catalogs; they didnāt list all their products online, and even if they did, our internet was dialup and usage was moderated by parents).
We would fantasize about which skateboards we were going to buy next — or rather, which ones we were going to ask our parents to purchase for us as birthday presents.
Little memories like leafing through CCS Catalogs before, during, and after school bring a smile to my face. And they make the days a little easier to get through.
So in this post, Iām going to show how to perform basic image segmentation using Python and OpenCV.
And weāll give it a little skateboarding theme as well, just to pay homage to a friend whose memory weighs heavy on my mind.
Looking for the source code to this post?
Jump Right To The Downloads SectionOpenCV and Python versions:
This example will run on Python 2.7/Python 3.4+ and OpenCV 2.4.X/OpenCV 3.0+.
The cv2.threshold
Function
Letās start by taking a look at the cv2.threshold function signature:
(T, threshImage) = cv2.threshold(src, thresh, maxval, type)
The first parameter is our source image, or the image that we want to perform thresholding on. This image should be grayscale.
The second parameter, thresh
, is the threshold value which is used to classify the pixel intensities in the grayscale image.
The third parameter, maxval
, is the pixel value used if any given pixel in the image passes the thresh
test.
Finally, the fourth parameter is the thresholding method to be used. The type
value can be any of:
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO
cv2.THRESH_TOZERO_INV
Sound complicated? It’s not — Iāll show you examples for each of these thresholding types.
The cv2.threshold
then returns a tuple of two values. The first value, T
, is the value that was used for the thresholding. In our case, this will be the same value as thresh
that we pass into the cv2.threshold
function.
The second value is our actual thresholded image.
Anyway, letās go ahead and explore some code.
Thresholding: Simple Image Segmentation using OpenCV
There are many forms of image segmentation.
Clustering. Compression. Edge detection. Region-growing. Graph partitioning. Watershed. The list goes on.
But in the beginning, there was only the most basic type of image segmentation: thresholding.
Letās discover how to perform simple image segmentation using OpenCV. Open up your favorite editor, create a file named threshold.py
, and letās get started:
# import the necessary packages import argparse import cv2 # construct the argument parser and parse the arguments ap = argparse.ArgumentParser() ap.add_argument("-i", "--image", required = True, help = "Path to the image to be thresholded") ap.add_argument("-t", "--threshold", type = int, default = 128, help = "Threshold value") args = vars(ap.parse_args()) # load the image and convert it to grayscale image = cv2.imread(args["image"]) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # initialize the list of threshold methods methods = [ ("THRESH_BINARY", cv2.THRESH_BINARY), ("THRESH_BINARY_INV", cv2.THRESH_BINARY_INV), ("THRESH_TRUNC", cv2.THRESH_TRUNC), ("THRESH_TOZERO", cv2.THRESH_TOZERO), ("THRESH_TOZERO_INV", cv2.THRESH_TOZERO_INV)] # loop over the threshold methods for (threshName, threshMethod) in methods: # threshold the image and show it (T, thresh) = cv2.threshold(gray, args["threshold"], 255, threshMethod) cv2.imshow(threshName, thresh) cv2.waitKey(0)
We’ll start by importing the two packages that we’ll need, argparse
and cv2
on Lines 2 and 3.
From there, we’ll parse our command line arguments on Lines 6-11. Here we’ll require two parameters. The first, --image
, is the path to the image that we want to threshold. The second, --threshold
, is the threshold value that will be passed into the cv2.threshold
function.
From there, we’ll load the image from disk and convert it to grayscale on Lines 14 and 15. We convert to grayscale since cv2.threshold
expects a single channel image.
Lines 18-23 defines our list of thresholding methods.
We loop over our thresholding methods starting on Line 26.
From there, we apply the actual threshold method on Line 28. We pass our grayscale image as the first argument, the command line supplied threshold value as the second argument, 255 (white) as our value for when the threshold test passes as our third argument, and finally the threshold method itself as the final parameter.
Finally, the thresholded image is displayed on Lines 29 and 30.
Let’s look at some results. Open up your terminal, navigate to our code directory, and execute the following command:
$ python threshold.py --image images/skateboard_decks.png --threshold 245
In this example we are using a value of 245 for our threshold test. If a pixel in the input image passes the threshold test, it will have the value set to 255.
Now, let’s take a look at the results:
Using cv2.THRESH_BINARY
Ā Ā the skateboards are segmented to be black with a white background.
To invert the colors, just use cv2.THRESH_BINARY_INV
Ā , as seen below:
Not bad. What else can we do?
Using cv2.THRESH_TRUNC
Ā Ā leaves the pixel intensities as they are if the source pixel is not greater than the supplied threshold.
Then we have cv2.THRESH_TOZERO
Ā Ā which sets the source pixel to zero if the source pixel is not greater than the supplied threshold:
Finally, we can invert this behavior as well using cv2.THRESH_TOZERO_INV
Ā :
Nothing to it!
What's next? I recommend PyImageSearch University.
30+ total classes • 39h 44m video • Last updated: 12/2021
★★★★★ 4.84 (128 Ratings) • 3,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:
- ✓ 30+ courses on essential computer vision, deep learning, and OpenCV topics
- ✓ 30+ Certificates of Completion
- ✓ 39h 44m on-demand video
- ✓ Brand new courses released every month, 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 500+ tutorials on PyImageSearch
- ✓ Easy one-click downloads for code, datasets, pre-trained models, etc.
- ✓ Access on mobile, laptop, desktop, etc.
Summary
In this blog post I showed you how to perform the most basic form of image segmentation: thresholding.
To perform thresholding we utilized the cv2.threshold
Ā Ā function.
OpenCV provides us with five basic thresholding methods, including:Ā cv2.THRESH_BINARY
,Ā cv2.THRESH_BINARY_INV
,Ā cv2.THRESH_TRUNC
,Ā cv2.THRESH_TOZERO
,Ā cv2.THRESH_TOZERO_INV
Ā .
Most importantly, be sure to play around with the thresh
Ā Ā value as it will give different results depending on what value you supply.
In future posts, I’ll show you how toĀ automaticallyĀ determine the threshold value, no parameter tuning required!
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!