Monday, 20 November 2017

Image Erosion and Dilation

public static Bitmap DilateAndErodeFilter(
                           this Bitmap sourceBitmap, 
                           int matrixSize,
                           MorphologyType morphType,
                           bool applyBlue = true,
                           bool applyGreen = true,
                           bool applyRed = true ) 
{
    BitmapData sourceData = 
               sourceBitmap.LockBits(new Rectangle (0, 0,
               sourceBitmap.Width, sourceBitmap.Height),
               ImageLockMode.ReadOnly, 
               PixelFormat.Format32bppArgb);

 
    byte[] pixelBuffer = new byte[sourceData.Stride * 
                                  sourceData.Height];

 
    byte[] resultBuffer = new byte[sourceData.Stride * 
                                   sourceData.Height];

 
    Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, 
                               pixelBuffer.Length);

 
    sourceBitmap.UnlockBits(sourceData);

 
    int filterOffset = (matrixSize - 1) / 2;
    int calcOffset = 0;

 
    int byteOffset = 0;

 
    byte blue = 0;
    byte green = 0;
    byte red = 0;

 
    byte morphResetValue = 0;

 
    if (morphType == MorphologyType.Erosion)
    {
        morphResetValue = 255;
    }

 
    for (int offsetY = filterOffset; offsetY < 
        sourceBitmap.Height - filterOffset; offsetY++)
    {
        for (int offsetX = filterOffset; offsetX < 
            sourceBitmap.Width - filterOffset; offsetX++)
        {
            byteOffset = offsetY * 
                         sourceData.Stride + 
                         offsetX * 4;

 
            blue = morphResetValue;
            green = morphResetValue;
            red = morphResetValue;

 
            if (morphType == MorphologyType.Dilation)
            {
                for (int filterY = -filterOffset;
                    filterY <= filterOffset; filterY++)
                {
                    for (int filterX = -filterOffset;
                        filterX <= filterOffset; filterX++)
                     {
                        calcOffset = byteOffset +
                                     (filterX * 4) +
                        (filterY * sourceData.Stride);

 
                        if (pixelBuffer[calcOffset] > blue)
                        {
                            blue = pixelBuffer[calcOffset];
                        }

 
                        if (pixelBuffer[calcOffset + 1] > green)
                        {
                            green = pixelBuffer[calcOffset + 1];
                        }

 
                        if (pixelBuffer[calcOffset + 2] > red)
                        {
                            red = pixelBuffer[calcOffset + 2];
                        }
                    }
                }
            }
            else if (morphType == MorphologyType .Erosion)
            {
                for (int filterY = -filterOffset;
                    filterY <= filterOffset; filterY++)
                {
                    for (int filterX = -filterOffset;
                        filterX <= filterOffset; filterX++)
                    {
                        calcOffset = byteOffset +
                                     (filterX * 4) +
                        (filterY * sourceData.Stride);

 
                        if (pixelBuffer[calcOffset] < blue)
                        {
                            blue = pixelBuffer[calcOffset];
                        }

 
                        if (pixelBuffer[calcOffset + 1] < green)
                        {
                            green = pixelBuffer[calcOffset + 1];
                        }

 
                        if (pixelBuffer[calcOffset + 2] < red)
                        {
                            red = pixelBuffer[calcOffset + 2];
                        }
                    }
                }
            }

 
            if (applyBlue == false )
            {
                blue = pixelBuffer[byteOffset];
            }

 
            if (applyGreen == false )
            {
                green = pixelBuffer[byteOffset + 1];
            }

 
            if (applyRed == false )
            {
                red = pixelBuffer[byteOffset + 2];
            }

 
            resultBuffer[byteOffset] = blue;
            resultBuffer[byteOffset + 1] = green;
            resultBuffer[byteOffset + 2] = red;
            resultBuffer[byteOffset + 3] = 255;
        }
    }

 
    Bitmap resultBitmap = new Bitmap (sourceBitmap.Width, 
                                     sourceBitmap.Height);

 
    BitmapData resultData = 
               resultBitmap.LockBits(new Rectangle (0, 0,
               resultBitmap.Width, resultBitmap.Height),
               ImageLockMode.WriteOnly,
               PixelFormat.Format32bppArgb);

 
    Marshal.Copy(resultBuffer, 0, resultData.Scan0, 
                               resultBuffer.Length);

 
    resultBitmap.UnlockBits(resultData);

 
    return resultBitmap;
}

No comments:

Post a Comment