Navigation

Related Articles

Back to Latest Articles

C# Tutorial: How To Apply Erosion To An Image


Andraz Krzisnik
C# Tutorial: How To Apply Erosion To An Image

Erosion is a morphological process, where pixels at an object boundaries are removed. Erosion and dilation are a pair of basic morphological transformations, which are completely opposite to one another.

How does it work?

When an image is processed it works with a kernel, which is placed on every pixel of the image. When a kernel is over a certain set of pixels, only the center pixel is evaluated for a change in intensity. All other neighboring pixel are just scanning the surface around it for a change in intensity. If they detect there is a change, the center pixel’s intensity is changed to the lowest intensity detected.

Usually we use erosion on binary images, or in other words images which contain only black and white. It works very well with Sobel edge detection filter, which produces such images, where edges od the objects are highlighted in white, while the background is completely black,

It is also very often used in combination with dilation and holes filling processes. While dilation adds pixels to edges, holes filling gives us an ability to whiten in the object. After these two processes we usually use erosion to get rid of that extra layer of pixels on the edges of our object in the image, so it is of the original size again.

Erosion function breakdown

First part of the function is dedicated to saving all your image data into an array, where we will read the image in numbers.

private Bitmap ErodeImage(Bitmap srcImage)
{
    int width = srcImage.Width;
    int height = srcImage.Height;

    Rectangle canvas = new Rectangle(0, 0, width, height);
    BitmapData srcData = srcImage.LockBits(canvas, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

    int bytes = srcData.Stride * srcData.Height;
    byte[] pixelBuffer = new byte[bytes];
    byte[] resultBuffer = new byte[bytes];

    Marshal.Copy(srcData.Scan0, pixelBuffer, 0, bytes);
    srcImage.UnlockBits(srcData);

Conversion to grayscale

Although it is mostly used for binary images, this code works for grayscale aswell.

float rgb;
for (int i = 0; i < bytes; i += 4)
{
    rgb = pixelBuffer[i] * .071f;
    rgb += pixelBuffer[i + 1] * .71f;
    rgb += pixelBuffer[i + 2] * .21f;
    pixelBuffer[i] = (byte)rgb;
    pixelBuffer[i + 1] = pixelBuffer[i];
    pixelBuffer[i + 2] = pixelBuffer[i];
    pixelBuffer[i + 3] = 255;
}

Apply erosion

Save processed data into the second array we created for holding the image data.

int kernelSize = 3;
int kernelOffset = (kernelSize - 1) / 2;
int calcOffset = 0;
int byteOffset = 0;

for (int y = kernelOffset; y < height - kernelOffset; y++)
{
    for (int x = kernelOffset; x < width - kernelOffset; x++)
    {
        byte value = 255;
        byteOffset = y * srcData.Stride + x * 4;
        for (int ykernel = -kernelOffset; ykernel <= kernelOffset; ykernel++)
        {
            for (int xkernel = -kernelOffset; xkernel <= kernelOffset; xkernel++)
            {
                if (kernel[ykernel + kernelOffset,xkernel + kernelOffset] == 1)
                {
                    calcOffset = byteOffset + ykernel * srcData.Stride + xkernel * 4;
                    value = Math.Min(value, pixelBuffer[calcOffset]);
                }
                else
                {
                    continue;
                }
            }
        }
        resultBuffer[byteOffset] = value;
        resultBuffer[byteOffset + 1] = value;
        resultBuffer[byteOffset + 2] = value;
        resultBuffer[byteOffset + 3] = 255;
    }
}

Output processed image

Create a new bitmap to which we copy image data from array that holds processed values.

    Bitmap result = new Bitmap(width, height);
    BitmapData resultData = result.LockBits(canvas, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
    Marshal.Copy(resultBuffer, 0, resultData.Scan0, bytes);
    result.UnlockBits(resultData);
    return result;
}

Downloadable content

Download Project

Now it’s your turn, let me know what you think in the comments below.

Related Articles

Image Noise

How To Make Gaussian Noise On Image – C# Guide

Gaussian noise on images is generated with Gaussian probability distribution function. It simulates noise that appears in practice.

Posted on by Andraz Krzisnik
C# Tutorial

C# Tutorial: Contrast Stretching with Normalization

This post is a short revision of Contrast Stretch post we already worked on in the past. Where we talked about histogram equalization, which is a little more complex method than...

Posted on by Andraz Krzisnik