Image Segmentation using Chromaticity and Image Differencing

Rafael Madrigal
3 min readSep 14, 2022

--

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, imshow
im1 = 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 np
bags = 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!

--

--

Rafael Madrigal

Data Scientist and Corporate Strategist. Can’t function without Coffee