Click here to Skip to main content
16,014,882 members
Articles / Multimedia / GDI+

Implement Dilation Algorithm using C#

Rate me:
Please Sign up or sign in to vote.
4.17/5 (10 votes)
4 Mar 2009CPOL2 min read 66.2K   2.9K   11   6
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.

C#
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
I am Software developer, working on web and Windows technology. Willing to accept challengces and try to complete them.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Mr.YunJi11-Oct-10 3:01
Mr.YunJi11-Oct-10 3:01 
GeneralMy vote of 4 Pin
SHAILASHREECHINTU1-Sep-10 1:48
SHAILASHREECHINTU1-Sep-10 1:48 
GeneralMy vote of 2 Pin
Qistoph4-Mar-09 20:50
Qistoph4-Mar-09 20:50 
GeneralRe: My vote of 2 Pin
Willi Deutschmann5-Mar-09 4:10
Willi Deutschmann5-Mar-09 4:10 
GeneralRe: My vote of 2 Pin
yvdh16-Mar-09 6:44
yvdh16-Mar-09 6:44 
GeneralNice Article Pin
Razan Paul (Raju)4-Mar-09 18:42
Razan Paul (Raju)4-Mar-09 18:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.