Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Implement Dilation Algorithm using C#

0.00/5 (No votes)
4 Mar 2009 1  
This code helps to implement Dilation algorithm using C#
DilationProject.PNG

Introduction

I am a C# developer and my domain is imaging. In C#, it's very hard to perform dilation. Dilation algorithm is a mathematical morphology which is required in Medical imaging project. This article will help people which are try to dilate images. Pointers are used in the code so it is much faster.

What is Dilation?

Dilation is one of the two basic operators in the area of mathematical morphology. The dilation is applied on the image in a single pass. During the passing through the image, the structuring element is applied on each pixel of the image, such that the origin of the structuring element is applied on that particular pixel. In this case, the corresponding pixel of the output image contains the maximum of the pixels surrounding it. In this case, only those pixels are compared with each other, where the structuring element is contained.

Using the Code

This function accepts Source bitmap and returns dilated Bitmap. GetPixel and SetPixel functions have several drawbacks so we use Pointer. We access and modify a pixel value using Pointer. The next example utilizes the “unsafe” block in C#. Inside unsafe blocks, we have access to pointers from C#. The conclusion is that pointers in unsafe blocks are faster than GetPixel and SetPixel functions.

public Bitmap Dilate(Bitmap SrcImage)
{
    // Create Destination bitmap.
    Bitmap tempbmp = new Bitmap(SrcImage.Width,SrcImage.Height);

    // Take source bitmap data.
    BitmapData SrcData = SrcImage.LockBits(new Rectangle(0, 0,
        SrcImage.Width, SrcImage.Height), ImageLockMode.ReadOnly,
        PixelFormat.Format24bppRgb);

    // Take destination bitmap data.
    BitmapData DestData = tempbmp.LockBits(new Rectangle(0, 0, tempbmp.Width,
        tempbmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

    // Element array to used to dilate.
    byte[,] sElement = new byte[5, 5] { 
        {0,0,1,0,0},
        {0,1,1,1,0},
        {1,1,1,1,1},
        {0,1,1,1,0},
        {0,0,1,0,0}
    };

    // Element array size.
    int size = 5;
    byte max, clrValue;
    int radius = size / 2;
    int ir, jr;

    unsafe
    {

        // Loop for Columns.
        for (int colm = radius; colm < DestData.Height - radius; colm++)
        {
            // Initialise pointers to at row start.
            byte* ptr = (byte*)SrcData.Scan0 + (colm * SrcData.Stride);
            byte* dstPtr = (byte*)DestData.Scan0 + (colm * SrcData.Stride);

            // Loop for Row item.
            for (int row = radius; row < DestData.Width - radius; row++)
            {
                max = 0;
                clrValue = 0;

                // Loops for element array.
                for (int eleColm = 0; eleColm < 5; eleColm++)
                {
                    ir = eleColm - radius;
                    byte* tempPtr = (byte*)SrcData.Scan0 + 
                        ((colm + ir) * SrcData.Stride);

                    for (int eleRow = 0; eleRow < 5; eleRow++)
                    {
                        jr = eleRow - radius;

                        // Get neightbour element color value.
                        clrValue = (byte)((tempPtr[row * 3 + jr] + 
                            tempPtr[row * 3 + jr + 1] + tempPtr[row * 3 + jr + 2]) / 3);

                        if (max < clrValue)
                        {
                            if (sElement[eleColm, eleRow] != 0)
                                max = clrValue;
                        }
                    }
                }

                dstPtr[0] = dstPtr[1] = dstPtr[2] = max;

                ptr += 3;
                dstPtr += 3;
            }
        }
    }

    // Dispose all Bitmap data.
    SrcImage.UnlockBits(SrcData);
    tempbmp.UnlockBits(DestData);

    // return dilated bitmap.
    return tempbmp;
}

In this function, we calculate the start and end addresses of the image structure, thinking that it is a 1D linear array. We increment the pointer from start to end addresses and get values in between. Calculate maximum from the surrounding pixel and assign maximum pixel to dilated image pointers.

Points of Interest

Dilation of pixel with its neighboring pixels is really good. This algorithm also helps me to implement erosion algorithm using C#.

History

  • 4th March, 2009: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here