Related Articles

Back to Latest Articles

How To Make Granulometry Work With C#

Granulometry is a grayscale morphological operation in image processing for estimating distribution of different sized particles.

Andraz Krzisnik
How To Make Granulometry Work With C#

Granulometry is a morphological operation in image processing, with which we can estimate particle size distribution. In other words, if we had an image with different sized particles, we can detect which sizes dominate in numbers.

This process involves more fundamental morphological operations, like grayscale opening, erosion and dilation. Well, it all boils down to erosion and dilation, since opening is just a sequence of the two.

When we’re talking about morphological opening, we just need to remember that we apply erosion first and dilation second. The purpose of this process is to remove objects that are smaller than the structuring element.

In case you’re not yet familiar with what a structuring element is, we can compare it to kernel we use in convolution. However, morphological processes are non-linear while convolution is linear. In other words, we don’t do any computation, only comparison between values in structuring element and pixel values it overlaps.

How does granulometry work?

As we mentioned before, it deals with determining the size distribution of particles. However, particles are rarely neatly separated in practice. Therefore we will need an algorithm that estimates this distribution without identifying and measuring individual particles.

Firstly, we need to apply a series of openings on input image. However, the difference between these openings are different sizes of structuring elements. You see, the larger the structuring element we use, more lighter pixels will become dimmer.

We can sum up all pixel values from each opening result separately. And finally, we can get the difference between these summed values, adjacent based on sorted structuring element size. In other words, we put each sum of intesities in an array and get the difference between each neighbouring sum.

Our final result will be a plotted chart, which will show these differences for each structuring element size we used in the series.


I wrote a function that applies the process we described above. However, it does include functions for grayscale erosion and dilation, which I already included on another post. Therefore, I won’t show the same code on this guide.

But, as for all other guides, you’ll be able to download the whole demo project solution and examine it in its entirety. Following function returns an array of sum differences between each structuring element it applies.

public static int[] Granulometry(this Bitmap image)
         int w = image.Width;
         int h = image.Height;

         BitmapData image_data = image.LockBits(
             new Rectangle(0, 0, w, h),

         int bytes = image_data.Stride * image_data.Height;
         byte[] buffer = new byte[bytes];

         Marshal.Copy(image_data.Scan0, buffer, 0, bytes);

         int[] result = new int[8];

         for (int i = 0; i < 8; i++)
             byte[] opening = buffer.Erode(image_data, i * 5);
             opening = opening.Dilate(image_data, i * 5);
             result[i] = 0;
             for (int j = 0; j < bytes; j += 3)
                 result[i] += opening[j];

             if (i != 0)
                 result[i - 1] -= result[i];

         return result;


I hope this tutorial helped you understand the process of granulometry a little better. As I mentioned before, you can also download the whole project and try it out yourself.

Related Articles

Morphological Processes

How To Make Extraction Of Connected Components In C#

Extraction of connected components in image processing is a morphological process, where we isolate object to a separate image.

Posted on by Andraz Krzisnik
Order-Statistic Filters

How To Make Max And Min Filter In Image Processing

Max and min filter is one of the order-statistic filter we can use to process image data in spatial domain. This tutorial shows it with C#.

Posted on by Andraz Krzisnik