In Part 1, we were able to discuss 3 Different Techniques(Thresholding, Otsu’s, and HSV Color Space) to segment different objects in an image.
This time, we will show a much more defined way of segmenting the objects using a much more complicated technique that is used for complicated images.
Let us say we have different kinds of unique colors in our image, how can we leverage an Image Processing technique to show the uniqueness of each pixel values?
The best way to do this is by using Chromaticity Segmentation.
In a sense, Chromaticity Segmentation looks at the combination of the pixel values within the image and maps it to the red and green channel to determine the proportion. Chromaticity Segmentation can be also coined as RG Chromaticity.
To better show how it works, let us do some experiments:
Let us load our old sample from part 1:
import numpy as np
from skimage.io import imshow, imread
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
sample = imread('flowers2.png')
sample_g = rgb2gray(sample)
fig, ax = plt.subplots(1,2,figsize=(10,5))
ax[0].imshow(sample)
ax[1].imshow(sample_g,cmap='gray')
ax[0].set_title('Colored Image',fontsize=15)
ax[1].set_title('Grayscale Image',fontsize=15)
plt.show()

For this article, we will still try to segment the white flower from the image. This time, we will be using RG Chromaticity as the Image Segmentation technique.
To better understand the image, we should first check the scatterplot of the pixel values of the images. The code to show this is as follows:
sample_R = sample[:,:,0]*1.0/sample.sum(axis=2)
sample_G = sample[:,:,1]*1.0/sample.sum(axis=2)
fig, ax = plt.subplots(1,2,figsize=(10,5))
ax[0].imshow(sample)
ax[1].scatter(sample_R.flatten(),sample_G.flatten())
ax[0].set_title('Colored Image',fontsize=15)
ax[1].set_title('Pixel Values',fontsize=15)
ax[1].set_xlabel('Red Channel',fontsize=10)
ax[1].set_ylabel('Green Channel',fontsize=10)
plt.tight_layout()
plt.show()

Figure 2 shows the scatter plot concerning the red channel as the x-axis and the green channel as the y-axis. Notice that the pixel values are more evident on the high-intensity green channel pixel values.
To be able to segment the white flower, we should first define a sample patch in the image. The code for that is as follows:
from matplotlib.patches import Rectangle
fig, ax = plt.subplots(1,2,figsize=(10,10))
ax[0].imshow(sample)
ax[0].add_patch(Rectangle((590, 570), 100, 100, edgecolor='r', facecolor='none'));
ax[0].set_title('Patch Location',fontsize=15)
#Showing Patch
patch = sample[570:670, 590:680]
ax[1].imshow(patch)
ax[1].set_title('Patch',fontsize=15)
plt.show()

Notice in Figure 3 that we used the whitest part of the flower because we would only segment the pixel values that are the same as this patch pixel value. To visualize that, we can plot the scatter plot of the patch itself:
patch_R = patch[:,:,0]*1.0/patch.sum(axis=2)
patch_G = patch[:,:,1]*1.0/patch.sum(axis=2)
fig, ax = plt.subplots(1,2,figsize=(10,5))
ax[0].imshow(patch)
ax[1].scatter(patch_R.flatten(),patch_G.flatten())
ax[0].set_title('Patch',fontsize=15)
ax[1].set_title('Pixel Values',fontsize=15)
ax[1].set_xlabel('Red Channel',fontsize=10)
ax[1].set_ylabel('Green Channel',fontsize=10)
ax[1].set_xlim(0,1)
ax[1].set_ylim(0,1)
plt.tight_layout()
plt.show()

Figure 4 shows that the pixel values for the red channel and green channel are situated only in the middle of the plot. To segment the white flower, we would want all the pixel values within this region.
To segment it, we would take the standard deviation and the mean of the patch initialized.
std_patch_R = np.std(patch_R.flatten())
mean_patch_R = np.mean(patch_R.flatten())
std_patch_G = np.std(patch_G.flatten())
mean_patch_G = np.mean(patch_G.flatten())
def gaussian(p,mean,std):
return np.exp(-(p-mean)**2/(2*std**2))*(1/(std*((2*np.pi)**0.5)))
After getting the mean and standard deviation, we would interpolate the original image to the patch so that it will follow the distribution. For this article, we used the Gaussian distribution as our distribution curve.
prob_R = gaussian(sample_R,mean_patch_R,std_patch_R)
prob_G = gaussian(sample_G,mean_patch_G,std_patch_G)
fig, ax = plt.subplots(1,3,figsize=(15,10))
ax[0].imshow(sample_g,cmap='gray')
ax[1].imshow(prob_R,cmap='gray')
ax[2].imshow(prob_R,cmap='gray')
ax[1].set_title('Grayscale',fontsize=15)
ax[1].set_title('Red Channel',fontsize=15)
ax[2].set_title('Green Channel',fontsize=15)
plt.show()

Figure 5 shows the results of getting the interpolated values for the red and green channel, notice that in the grayscale mode, we were able to segment the flower bouquets also.
To get the white flower specific part, we would need to multiply the results.
prob = prob_R * prob_G
fig, ax = plt.subplots(1,2,figsize=(10,10))
ax[0].imshow(sample)
ax[1].imshow(prob,cmap='gray')
ax[0].set_title('Colored Image',fontsize=15)
ax[1].set_title('Final Image',fontsize=15)
plt.show()

Figure 6 shows our Final Image using the Rg Chromaticity Technique. The results show that RG Chromaticity is actually wat better when segmenting objects that have varying color spaces.
Summary
For this article, we were able to show how we can use the red and green channels as a way to segment objects in an image. We were able also to show how the pixel values can be used to segment the image from its background using the chromaticity plot. In conclusion, Image Segmentation is very helpful in creating datasets for future Data Science Projects.
Stay Tuned for more articles about Image Processing!