Image Segmentation using Chromaticity and Image Differencing
Previously, we introduced Otsu’s Method and Multi-Otsu’s method as alternative image segmentation techniques. This time, we look at Chromaticity and Image Differencing
Image Differencing
Image differencing mainly takes the difference between two images to segment regions that are the same or identical. A classic example of this is the case of “Spot the Difference” where we are tasked to look for the difference between the two images. To do this in scikit-image, we just take the difference between the grayscale version of the two images.
from skimage.color import rgb2gray
from skimage.io import imread, imshowim1 = imread('Image1.jpg')
im2 = imread('Image2.jpg')diff = rgb2gray(im1)-rgb2gray(im2)
In the image, we identify the headband, the balloon, the butterfly, the bunny, the bush, the fountain, and the sun as the main differences between the two images.
Chromaticity Segmentation
Chromaticity segmentation relies on the RG Chromaticity space, a 2D representation of RGB that removes the information regarding the intensity values of the colors. Using the formula below, we only compute for r and g and assume b to be the balance such that r+g+b=1.
But how do we use this?
from skimage.io import imread, imshow
import matplotlib.pyplot as plt
import numpy as npbags = imread('bags.png')
imshow(bags)
- We need to convert our image to the RG space by performing the operations above.
bags_R = bags[:,:,0]*1.0/bags.sum(axis=2)
bags_G = bags[:,:,1]*1.0/bags.sum(axis=2)
- Obtain a reference patch and translate that to the RG space using the same method
patch = bags[250:300,300:350,:]
imshow(patch)patch_R = patch[:,:,0]*1.0/patch.sum(axis=2)
patch_G = patch[:,:,1]*1.0/patch.sum(axis=2)
- Fit a Gaussian probability distribution using the patch RG values. The distribution will dictate which pixel belongs to the color of interest. To define a gaussian curve, we computed the mean and standard deviation for R and G of the patch image.
# For the R axis
std_patch_R = np.std(patch_R.flatten())
mean_patch_R = np.mean(patch_R.flatten())# For the G axis
std_patch_G = np.std(patch_G.flatten())
mean_patch_G = np.mean(patch_G.flatten())# Define the Gaussian Distribution
def gaussian(p,mean,std):
return np.exp(-(p-mean)**2/(2*std**2))*(1/(std*((2*np.pi)**0.5)))
- Apply the gaussian to your image. Note that the function computes the probability that the regions in the image belong to the distribution you defined. That is, if the gaussian is for the R-axis, then the gaussian will return the probability that a pixel in the original image belongs to the R distribution. Considering this, we need to take the intersection of the Gaussian for R and G to isolate our image.
prob_R = gaussian(bags_R,mean_patch_R,std_patch_R)
plt.imshow(prob_R)
prob_G = gaussian(bags_G,mean_patch_G,std_patch_G)
plt.imshow(prob_G)
prob=prob_R * prob_G
plt.imshow(prob)
- Lastly, we create a mask by binarizing the selection
plt.imshow(prob>0.00000001)
SUCCESS!
Wrapping Up
In this article, we introduced two image segmentation techniques called image differencing and chromaticity segmentation which are useful in segmenting very complicated images. They are indeed very powerful additions to our image processing toolkits!