How To Make Image Erosion Work With C#
Image erosion is one of the fundamental morphological operations and this tutorial explains how it works and demonstrates it in C#.
Filter by Category
Image erosion is one of the fundamental morphological operations and this tutorial explains how it works and demonstrates it in C#.
This tutorial shows how image watermarking works by implementing it with C# and we describe various purposes that watermarks have as well.
This tutorial shows how to use colors for image segmentation applied in C#. I explain the basics of applying it in different color spaces.
This color image smoothing and sharpening tutorial shows how to apply convolution for blurring and sharpening images with C#.
This guide shows how to apply color histogram equalization with iterative equalization of the image by using nth root or nth power.
Color balancing is one of the processes we use to adjust images, which are either on the weaker or heavier side for any of the color channels.
This guide shows how to apply image tone corrections for flat, dark and light images. The purpose of it is to adjust brightness and contrast.
Color slicing is a color image processing technique, which only shows colors in a certain color space making objects stand out.
False color or pseudocolor image processing coupled with intensity slicing is useful for emphasizing shapes that might be hidden to our eyes.
This guide shows how to convert RGB to HSI image data and also how to convert it back from HSI to RGB to make it displayable on screen.
We will delve into morphological processing, more preciselly we’ll look into how image erosion works. Furthermore, erosion is one of the fundamental morphological operations.
Therefore, it’s going to act as a stepping stone for understanding other more complicated morphological operations. However, I’ll make sure to explain each process separately, so you won’t need to come back to this post.
When we’re working with morphological operations, we represent our image data differently as we would normally . What I mean by that is, we divide our image into sets.
For example, when we’re deling with binary images, which only have two colors, black or white, we have sets of foreground and background pixels. That being said, we’re not limited to processing only these kind of images with this technique.
However in this guide, we’ll focus on applying erosion on binary images as it’s the simplest way of demonstrating it. Morphological processes work by sliding structuring element across the image, which is similar to kernel in convolution.
Therefore, it’s more intuitive, to explain it as we were doing convolution. With image erosion, we have structuring element or kernel that has all true values or in other words, max 8-bit value, 255. We put it on top of the image and if all values cover white pixels, we set the center or origin pixel white on the resulting image.
The set of foreground pixels usually represent an object in the image. But, because we take all foreground pixels into one set, it can also represent multiple disjoint objects.
As we said before, we put structuring element on top of image and compare if all white pixels coincide. And if they do, we set white pixel on the resulting image where the center position of the structuring element is on the input image.
However, these structuring elements can be of different shapes, which will erode foreground pixels differently.
We can view image erosion as a morphological filtering operation, with which we remove details smaller than structuring element.
I’ve written a function that demonstrates this process with a square structuring element.
public static Bitmap Erosion(this Bitmap image, int se_dim)
{
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];
byte[] result = new byte[bytes];
Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
image.UnlockBits(image_data);
int o = (se_dim - 1) / 2;
for (int i = o; i < w - o; i++)
{
for (int j = o; j < h - o; j++)
{
int position = i * 3 + j * image_data.Stride;
byte val = 255;
for (int x = -o; x <= o ; x++)
{
for (int y = -o; y <= o; y++)
{
int kposition = position + x * 3 + y * image_data.Stride;
val = Math.Min(val, buffer[kposition]);
}
}
for (int c = 0; c < 3; c++)
{
result[position + c] = val;
}
}
}
Bitmap res_img = new Bitmap(w, h);
BitmapData res_data = res_img.LockBits(
new Rectangle(0, 0, w, h),
ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);
Marshal.Copy(result, 0, res_data.Scan0, bytes);
res_img.UnlockBits(res_data);
return res_img;
}
I hope this tutorial was helpful in understanding image erosion.
You can also download the demonstration project yourself and try it out or modify it.