Image segmentation using thresholding by Otsu's Method, RGB & HSV color space
Image segmentation using thresholding by Otsu's Method, RGB and HSV color space
As mentioned on the previous post. There are cases we need to extract an object of interest from the main image. To do this, we need to identify and extract a specific signature of that object of interest. In this post, we will discuss the following: Thresholding, Otsu's Method, and Color Image Segmentation
Let's begin by loading the python libraries we will be using.
import matplotlib.pyplot as plt
import numpy as np
from skimage.io import imread, imshow
from skimage.color import rgb2gray
from skimage.exposure import histogram, cumulative_distribution
Let's say, for example, we wanted to extract the blue pin has in this image.
Like before, let's get the grayscale value of the image.
We can try various thresholds to get a good mask.
From the given thresholds, subjectively 0.5 is the best to be used as the mask. Let's use that value as our mask.
That took a while to extract that pin.
But we can also use another approach using Otsu's threshold, which performs automatic image thresholding by minimizing the intra-class variance or maximizing the inter-class variance. To do this, Scikit-image has this library. Let's try it out.
from skimage.filters import threshold_otsu
Otsu's method and the selected threshold read almost the same value. We can use Otsu's if the object of interest can be easily extracted from the main image.
But what if we have this image below?
Can we extract an image using the same methods we used above?
Let's try using the Otsu method first.
We can see three pins which can be extracted. But we need to extract one.
How about using range of thresholds?
Well I suppose we can get the portion of white pin using the mask at threshold=0.9
Lets try to extract it.
Fair enough. But what if we need a particular pin from the image? If I only want red? or blue? or yellow?
To solve this, we can use Color Image Segmentation using RGB and HSV ColorSpace.
Let try to get the blue pin again using RGB method. To execute this, we need to
Get the difference between the color chanel and the grayscale values multiplied by 255.
Consider only the positive values and convert the rest to 0.
Get the new threshold (for this case we used otsu method)
Let's try the procedure for blue pin.
Now, let's try that method for red and green pins
green = pins[:,:,1] - pins_gray*255
green2 = np.where(green > 0, green, 0)
thresh = threshold_otsu(green2)
green_binary_otsu = green > thresh
red = pins[:,:,0] - pins_gray*255
red2 = np.where(red > 0, red, 0)
thresh = threshold_otsu(red2)
red_binary_otsu = red > thresh
Here are the masks
And here are the extracted pins.
It worked!
Wait, am I missing something? Ah yes, the yellow pin.
To segment the color with different shades and hues, we can use HSV color space to isolate it from the image.
We can perform trial and error with the above value to filter out the unwanted colors using the HSV channels.
For this example, I used the Hue and Value.
Looks like we have seperated the yellow pin head. But there are still residual parts. We can use the median_filter of scipy.ndimage to helpus filter these specs.
Alright! Thank you for making this far.
To summarize, we have successfully extracted our object of interest by creating a mask by thresholding and with the use of RGB and HSV Color spaces. We can perform trial and error for the threshold to determine the best value we can use, or we can use the Otsu's filter to select its recommended threshold automatically. We can take advantage of the color space channel, especially if the object of interest's color is either red, green, or blue. We can use the HSV color space and filter for Hue, Saturation, or Value values for colors in between. As already mentioned, the median filter can be used to clean up the remaining specs from the processed image.
Comments