Image Segmentation with Clustering | by Yağmur Çiğdem Aktaş | Towards Data Science

We overviewed Classical Image Segmentation methods in my previous post. Now it is time to examine AI-based Image Segmentation methods and we will start with Clustering.
Before diving into Image Segmentation with Clustering, let’s go over the topics like “What is Clustering?” “How to implement a basic Clustering method with Python?”
What is Clustering
It is nothing more than grouping given data according to their similarities and obtains different clusters at the end. According to the clustering method we use, the way we group the data changes. Let’s examine 2 different most used in Image Segmentation type: Partitioning Clustering and Fuzzy Clustering
Partitioning Clustering
Partitioning Clustering methods subdivides the data into k groups, where k is a number predefined by the user. For K-means Clustering which is the most popular Partitioning Cluster method
We choose k random points in the data as the center of clusters and assign each point to the nearest cluster by looking at the L2 distance between the point and the center.Compute the mean of each cluster, assign that mean value as the new center of the cluster.Reassign each data point to its closest cluster center. Repeat step 2.
We choose k random points in the data as the center of clusters and assign each point to the nearest cluster by looking at the L2 distance between the point and the center.
Compute the mean of each cluster, assign that mean value as the new center of the cluster.
Reassign each data point to its closest cluster center. Repeat step 2.
The process keeps going until no new assignment is performed (so the model is converged, there is nothing to go furthermore) or for a given number of iteration. Therefore, K-means Clustering is an iterative method where we can determine the iteration number too.
Now let’s visualize some random data applying K-means clustering for 10 iterations for each.
from sklearn.cluster import KMeansfrom sklearn.datasets import make_blobsimport numpy as npfrom matplotlib import pyplot as pltimport cv2""" Plot the data """data = np.array([[1, 2], [1, 4], [1, 0],[10, 2], [10, 4], [10, 0]])data = np.array([[1, 5], [3, 1], [10, 3], [10, 2], [10, 1], [1, 0], [2, 15], [0.5, 4.9], [5, 3], [7, 13], [18, 18], [1.9, 0.5]]) data = np.random.randint(100, size=(2,2))centers = [[1, 1], [-1, -1], [1, -1]]data, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)# Plot the dataplt.scatter(data[:,0],data[:,1])plt.xlabel('x'),plt.ylabel('y')plt.show()""" Visualize K means for each iteration """""" create an empty list for each cluster, k is the cluster number """k = 2clusters = [[[0 for _ in range(2)] for _ in range(1)] for _ in range(k)]for i in range(k):    clusters[i].pop() #if we dont do that, additional [0,0] points will be stayed added in our data    """ Visualize each iteration. """for i in range(1,10):    kmeans = KMeans(n_clusters=k, random_state = 0, max_iter=i).fit(data)    for index,data_point in enumerate(data):        clusters[kmeans.labels_[index]].append(list(data_point))            for i in range(k):        clusters[i] = np.array(clusters[i])        plt.scatter(clusters[i][:,0],clusters[i][:,1])        clusters[i] = clusters[i].tolist()     plt.show()
We see even at the first iteration we obtain the final result. Because the data is pretty small and initial clustering works well. Let’s run the same code for the data randomly generated as below and group them into 5 clusters.
centers = [[1, 1], [-1, -1], [1, -1]]data, _ = make_blobs(n_samples=10000, centers=centers, cluster_std=0.6)
Now we see better how in each iteration the clusters get updated!
Time to apply K-means Clustering on a real image and get segmented output!
""" Image Segmentation """img = cv2.imread("bird1.jpg", cv2.IMREAD_UNCHANGED) img = cv2.imread("birds2.jpg", cv2.IMREAD_UNCHANGED)  img = cv2.imread("peppers3.jpg", cv2.IMREAD_UNCHANGED)  vectorized = img.reshape((-1,3))kmeans = KMeans(n_clusters=5, random_state = 0, n_init=5).fit(vectorized)centers = np.uint8(kmeans.cluster_centers_)segmented_data = centers[kmeans.labels_.flatten()] segmented_image = segmented_data.reshape((img.shape))plt.imshow(segmented_image)plt.pause(1)
You can realize that I didn’t use max_iter which determined the iteration number parameter that time. I leave that decision to the model so segmentation stops when no change in clusters occurs. On the other hand, the n_init parameter determines how many different trials will be completed with different random cluster centers in the initial step. The algorithm chooses the best fit, which gives the best segmentation.
We can realize with increasing k, the result gets better and more detailed!
Here is the github link for the code used in that section :
Fuzzy Clustering
Fuzzy Clustering is a hard clustering type while Partitioning Clustering is called soft. The reason for that is while in Partitioning Clustering, 1 data point may have only in 1 cluster, in Fuzzy Clustering we have the probabilities of a data point for each cluster and they may belong to any cluster at this probability level.
Not let’s examine the most common Fuzzy Clustering type Fuzzy C-Mean Clustering and see how to calculate the probabilities of points, the center of clusters, etc. [1]
Initialize the probability matrix randomly. So, assign weights to each data — cluster pair which refers to the probability of being in cluster C for data X.Calculate the center of clusters (centroids),Calculate new probabilities according to the new center of clusters.Repeat 2. and 3. steps until the centers doesn’t change or for a given iteration number
Initialize the probability matrix randomly. So, assign weights to each data — cluster pair which refers to the probability of being in cluster C for data X.
Calculate the center of clusters (centroids),
Calculate new probabilities according to the new center of clusters.
Repeat 2. and 3. steps until the centers doesn’t change or for a given iteration number
Let’s visualize an example case :
We have 4 data points p1, p2, p3, p4 2-dimensional, so we have x and y coordinates of the points and we want to group them into 2 clusters.
We initialize the weight matrix randomly:
We initialize the weight matrix randomly:
2. We calculate the centroids of clusters according to that initial probabilities with the following formula:
Note that fuzzy parameter is something we should choose like Cluster number and it can be chosen between 1 < m < ∞
Let’s apply the formula for our example case by choosing m = 2 :
Since we have 2D points, the center of the cluster is 2D too. So we calculate C1x (x coordinate of the first cluster) using x coordinates of our points and C1y (y coordinate of the first cluster) using y coordinates of our points).
When we apply the same formula for C2 too, we obtain the following
We obtained our cluster centers, now it’s time to calculate the probabilities of points according to that new cluster centers.
3. We calculate new probabilities — weights using the following formula:
Don’t forget m = 2 in our case, so 1/m-1 = 1.
and so on! I didn’t calculate each weight for each point and cluster but wanted to show the logic manually for each step.
I hope it was clear the fundamental logic and application of Fuzzy C Means Clustering. Now it’s time to do some experiments and examine the results.
Choosing fuzzy parameter m too big causes the result to be distorted. Again we see with increasing cluster numbers we obtain a more detailed and better-segmented result.
If you use Linux, you can try to use the fuzzy c means module from PyPI [1], I had some trouble installing it on windows even though I used pip install fuzzy-c-means[windows] command as suggested. Thanks to [2] for fuzzy c means implementation from scratch, I used that one while preparing that last part.
See you in the Image Segmentation with Neural Networks part! 👐
[1] https://pypi.org/project/fuzzy-c-means/
[2]https://github.com/jeongHwarr/various_FCM_segmentation/blob/master/FCM.py
In this post, all the images used for making experiments with different code parts are taken from unsplash.com