How To Make Granulometry Work With C#
Granulometry is a grayscale morphological operation in image processing for estimating distribution of different sized particles.
Filter by Category
Granulometry is a grayscale morphological operation in image processing for estimating distribution of different sized particles.
Top hat transformation is a grayscale morphological operation in image processing, we can use for extraction of certain objects in the image.
Morphological gradient is a grayscale morphological operation in image processing, which emphasized boundaries and supresses homogenous areas
Morphological smoothing is an image processing technique, which includes grayscale erosion and dilation, and grayscale opening and closing
Automatic algorithm for filling holes is a sequence of morphological operations in reconstruction branch, which fills all holes in the image.
Opening by reconstruction is a morphological operation in image processing for removing small objects and recovering shape accurately after.
Geodesic dilation and erosion are fundamental morphological reconstruction algorithms which yield the same result if left to converge.
Pruning in image processing is a morphological operation for removing spurs. It serves mainly as a post processing technique for cleaning up.
Skeletonization is a morphological process in image processing, which extracts the center lines of all shapes, which look like their skeleton
Thickening is a morphological operation in image processing, which adds foreground or white pixels to objects in order to thicken them.
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.
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),
ImageLockMode.ReadOnly,
PixelFormat.Format24bppRgb);
int bytes = image_data.Stride * image_data.Height;
byte[] buffer = new byte[bytes];
Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
image.UnlockBits(image_data);
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.