K-Means Clustering for Image Segmentation using OpenCV in Python
By: Ali Hassan
Tags: Machine Learning, Image Segmentation, Computer Vision, Opencv, K Means Clustering

Now Its Play Time!

First of all, we need to import required libraries for our image segmentation task. In our situation the problem requires lot of vector calculation. Default python data structures are not designed for high performance vector computation. So, we are using numpy (the core library for scientific computing in Python. It provides a high-performance multidimensional array object, and tools for working with these arrays). For plotting image, we are using matplotlib, it provides an object-oriented API for embedding plots into our notebook. And most important library in computer vision cv2, a library designed to solve computer vision problems. Please install those libraries if it is not already available in your system.

Now we need to pre-process our image to ensure the input pixel compatible to the cv2.kmean algorithm. So, we are reshaping image pixels to 2D array of RGB values and converting each color value to float 32 formats.

Here we are using an inbuild function(kmeans) available in cv2 for clustering pixels of our image. So, we can go through the arguments of cv2.kmean. Mainly it has 5 arguments. It returning 3 values back which is compactness, labels and centers.

CV2.KMEANS Parameters

samples : It should be of np.float32 data type, and each feature should be put in a single column.

nclusters(K) : Number of clusters required at end

criteria : It is the iteration termination criteria. When this criteria is satisfied, algorithm iteration stops. Actually, it should be a tuple of 3 parameters. They are ( type, max_iter, epsilon ):

- type of termination criteria. It has 3 flags as below:

( 1. cv.TERM_CRITERIA_EPS — stop the algorithm iteration if specified accuracy, epsilon, is reached.

2. cv.TERM_CRITERIA_MAX_ITER — stop the algorithm after the specified number of iterations, max_iter.

3. cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER — stop the iteration when any of the above condition is met).

- max_iter : An integer specifying maximum number of iterations.

- epsilon : Required accuracy

- type of termination criteria. It has 3 flags as below: ( 1. cv.TERM_CRITERIA_EPS — stop the algorithm iteration if specified accuracy, epsilon, is reached. 2. cv.TERM_CRITERIA_MAX_ITER — stop the algorithm after the specified number of iterations, max_iter. 3. cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER — stop the iteration when any of the above condition is met). - max_iter : An integer specifying maximum number of iterations. - epsilon : Required accuracy attempts: Flag to specify the number of times the algorithm is executed using different initial labelling. The algorithm returns the labels that yield the best compactness. This compactness is returned as output.

flags: This flag is used to specify how initial centers are taken. Normally two flags are used for this : cv.KMEANS_PP_CENTERS and cv.KMEANS_RANDOM_CENTERS.

CV2.KMEANS Return Value

compactness : It is the sum of squared distance from each point to their corresponding centers.

labels : This is the label array (i.e. labels which denotes which pixel belongs to which cluster)

centers : This is array of centers of clusters

Now we are carried out the clustering process. Each individual pixel is assigned to one of five cluster, we can get each pixel’s clusters number from the labels list. For viewing segmented image, we need to construct the image using centers and labels. Now the centers are in form of float32 we need to convert it back to integer format. And also we need to convert labels to pixel values of respective centers, Luckily, we have an operation in numpy that can be used for constructing a numpy array, this operation can populates the numpy array according to selected indices. Example suppose we have a numpy array a= [1 2 3], so if we need to construct a numpy array of [1 2 3 2 1] we can easily populate using the expression a [[0 1 2 1 0]]. Here we are using this same concept to create pixels according to centers value and labels assigned to individual pixels. Last step is reshaping the newly created numpy array to required format, here we are getting the shape of image by simply using shape attribute of image.