Image Classification Tutorial using K-Means in C#

Image Classification Tutorial with K-Means source code.

Source Code Link: Discover Groups – Similar Photos

In this tutorial we are going to build a simple image classifier. The only prerequisite is to have a good knowledge on K-Means clustering algorithm.

If you need a refresher you can check some of my other posts on K-Means:

Image Classification

Grouping images into semantically meaningful categories using low-level visual features is a challenging and important problem in the area of Computer Vision.

We can define it as a process of assigning an input image with a label from a fixed set of categories.

Image Dataset
Image 1: Dataset

So if we want to group these images using K-Means, first we need to choose the number of clusters. In order to do that we can use the “Elbow Method“. Or we can guess the correct K just from looking at the dataset.

Visually we can group these pictures in 4 categories.

  • Green meadows
  • Blue underwater worlds
  • White winter fairy tales
  • Orange autumn nature

That is a quite easy task for a human. But how can we do the same type of grouping using K-Means?

Feature Extraction

In machine learning and pattern recognition, a feature is defined as a measurable property or characteristic of the object you’re trying to analyze. That being said, we need to choose informative, discriminating and independent features that can be used for analysis.

One of the most prominent features in our dataset is the color. Meadows are green, deep water is blue, winter is best described by the white color and autumn is defined by the overly orange leaves.

As you can see feature extraction involves reducing the number of resources required to describe a large set of data. As a result, feature extraction is related to dimensionality reduction.

In this project we are not going to look at complex features. But just extract the color component of the image and classify it.

RGB

In colored images, each pixel can be represented by a vector of three numbers (each ranging from 0 to 255) for the three primary color channels: red, green, and blue. These three red, green, and blue (RGBvalues are used together to decide the color of that pixel.

This means that our input vector will have three values. Therefore, we obtain the input vector with the following method:

double[] GetAverageRGB(Bitmap bmpImage)
{
     double[] result = new double[3];
     int numberOfPixlels = 0;

     for (int i = 0; i < bmpImage.Width; i++)
     {
          for (int j = 0; j < bmpImage.Height; j++)
          {
               Color c = bmpImage.GetPixel(i, j);
               result[0] += c.R;
               result[1] += c.G;
               result[2] += c.B;
               numberOfPixlels++;
          }
     }
     result[0] /= numberOfPixlels;
     result[1] /= numberOfPixlels;
     result[2] /= numberOfPixlels;
     return result;
}

GetAverageRGB method is creating an input vector by calculating the mean over the RGB channels of the image.

As you can see from the dataset, all images have some dominant color. As a result, we are going to use the color component to find groups in the dataset.

The input for each image, will look something like this:

Input Vector = [Mean R, Mean G, Mean B]

After that, it’s K-Means job to train on that dataset and classify new images.

K-Means

If you are unfamiliar with the K-Means clustering algorithm, you can check the following posts:

But, the main idea behind K-Means is to be able to cluster/group similar images by color. The expectation is that winter images will create a cluster, deep and underwater images will create it’s own and so on.

This notion is based on the feature extraction we did earlier. Since we are looking at the mean RGB for image, we can expect image grouping by color.

Now think about what other features are better and even more descriptive that will allow us even better clustering/grouping of our dataset.

8 Responses

  1. Hello there, i am niaz from china, Xinjiang University. i am a student of MS Software Eng. My research area is related to K-means clustering algo. i found your videos very helpful for my succession. and therefore i wana contact asap.

  2. Hello there thank you for sharing your work and knowledge. I am trying to implement Local Binary Patterns and K-means. Do you have any advice or source that could help me?
    Thank you very much

    1. Hi,
      You have a very interesting project. Usually LBP are combined with Histogram of Oriented Gradients (HOG) descriptor to improve the detection performance so I am not quite sure where K-Means fits here. K-Means may help you determine the Key-Point positions. Usually a lot of points are concentrated near the important parts of the image and you can use K-Means with a fixed window-size to cluster those points. It really depends from the problem you are trying to solve.

  3. Hi, i have downloaded this source code, however it is throwing some error saying “could not find the file” or “could not load complete” “some of the files are deleted or renamed”.

    could you please help me if I am missing some step? or do i need any additional files/libs apart from these?

    1. Hey, were you able to solve the problem?
      You should not need any additional files or libraries. Everything is included.
      Let me know if you need help.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top