Article purpose
The purpose of this article is aimed at exploring the concepts of Image Erosion, Image Dilation, Open Morphology and Closed Morphology. In addition this article extends conventional Image Erosion and Dilation implementations through partial colour variations of Image Erosion and Dilation.
Sample source code
This article is accompanied by a sample source code Visual Studio project which is available for download here.
Using the sample application
Included in this article’s sample source code you’ll find a Windows Forms based sample application. The sample application can be used to test and replicate the concepts we explore in this article.
When executing the sample application source/input images can selected from the local file system by clicking the Load Image button. On the right-hand side of the sample application’s user interface users can adjust the provided controls in order to modify the method of filtering being implemented.
The three CheckBoxes labelled Red, Green and Blue relate to whether the relevant colour component will be regarded or not when implementing the configured image filter.
Users are required to select an image filter: Image Erosion, Image Dilation Open Morphology or Closed Morphology. The interface selection is expressed by means of four RadioButtons respectively labelled Dilate, Erode, Open and Closed.
The only other input required from a user comes in the form of selecting the filter intensity/filter size. The dropdown ComboxBox indicated as Filter Size provides the user with several intensity levels ranging from 3×3 to 17×17. Note: Larger filter sizes result in additional processing required when implementing the filter. Large images set to implement large sized filters may require more processor cycles.
Resulting filtered images can be saved to the local file system by clicking the Save Image button. The screenshot below illustrates the Image Erosion and Dilation sample application in action:
Mathematical Morphology
A description of Mathematical Morphology as expressed on Wikipedia:
Mathematical morphology (MM) is a theory and technique for the analysis and processing of geometrical structures, based on set theory, lattice theory, topology, and random functions. MM is most commonly applied to digital images, but it can be employed as well on graphs, surface meshes, solids, and many other spatial structures.
Topological and geometrical continuous-space concepts such as size, shape, convexity, connectivity, and geodesic distance, were introduced by MM on both continuous and discrete spaces. MM is also the foundation of morphological image processing, which consists of a set of operators that transform images according to the above characterizations.
MM was originally developed for binary images, and was later extended to grayscale functions and images. The subsequent generalization to complete lattices is widely accepted today as MM’s theoretical foundation.
In this article we explore Image Erosion, Dilation, as well as Open and Closed Morphology. The implementation of these image filters are significantly easier to grasp when compared to most definitions of Mathematical Morphology.
Image Erosion and Dilation
Image Erosion and Dilation are implementations of morphological filters, a subset of Mathematical Morphology. In simpler terms Image Dilation can be defined by this quote:
Dilation is one of the two basic operators in the area of mathematical morphology, the other being erosion. It is typically applied to binary images, but there are versions that work on grayscale images. The basic effect of the operator on a binary image is to gradually enlarge the boundaries of regions of foreground pixels (i.e. white pixels, typically). Thus areas of foreground pixels grow in size while holes within those regions become smaller.
Image Erosion being a related concept is defined by this quote:
Erosion is one of the two basic operators in the area of mathematical morphology, the other being dilation. It is typically applied to binary images, but there are versions that work on grayscale images. The basic effect of the operator on a binary image is to erode away the boundaries of regions of foreground pixels (i.e. white pixels, typically). Thus areas of foreground pixels shrink in size, and holes within those areas become larger.
From the definitions listed above we gather that Image Dilation increases the size of edges contained in an image. In contrast Image Erosion decreases or shrinks the size of an Image’s edges.
Open and Closed Morphology
Building upon the concepts of Image Erosion and Dilation this section explores Open and Closed Morphology. A good definition of Open Morphology can be expressed as follows:
The basic effect of an opening is somewhat like erosion in that it tends to remove some of the foreground (bright) pixels from the edges of regions of foreground pixels. However it is less destructive than erosion in general. As with other morphological operators, the exact operation is determined by a structuring element. The effect of the operator is to preserve foreground regions that have a similar shape to this structuring element, or that can completely contain the structuring element, while eliminating all other regions of foreground pixels.
In turn Closed Morphology can be defined as follows:
Closing is similar in some ways to dilation in that it tends to enlarge the boundaries of foreground (bright) regions in an image (and shrink background color holes in such regions), but it is less destructive of the original boundary shape. As with other morphological operators, the exact operation is determined by a structuring element. The effect of the operator is to preserve background regions that have a similar shape to this structuring element, or that can completely contain the structuring element, while eliminating all other regions of background pixels.
Implementing Image Erosion and Dilation
In this article we implement Image Erosion and Dilation by iterating each pixel contained within an image. The colour of each pixel is determined by taking into regard a pixel’s neighbouring pixels.
When implementing Image Dilation a pixel’s value is determined by comparing neighbouring pixels’ colour values, determining the highest colour value expressed amongst neighbouring pixels.
In contrast to Image Dilation we implement Image Erosion by also inspecting neighbouring pixels’ colour values, determining the lowest colour value expressed amongst neighbouring pixels.
In addition to conventional Image Erosion and Dilation the sample source code provides the ability to perform Image Erosion and Dilation targeting only specific colour components. The result of specific colour Image Erosion and Dilation produces images which express the effects of Image Erosion and Dilation only in certain colours. Depending on filter parameters specified Image edges appear to have a coloured glow or shadow.
The sample source code provides the definition for the DilateAndErodeFilter extension method, targeting the Bitmap class. The following code snippet details the implementation of the DilateAndErodeFilter extension method:
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; }
Implementing Open and Closed Morphology
The sample source code implements Open Morphology by first implementing Image Erosion on a source image, the resulting image is then filtered by implementing Image Dilation.
In a reverse fashion Closed Morphology is achieved by first implementing Image Dilation on a source image, which is then further filtered by implementing Image Erosion.
The sample source code defines the OpenMorphologyFilter and CloseMorphologyFilter extension methods, both targeting the Bitmap class. The implementation as follows:
public static Bitmap OpenMorphologyFilter( this Bitmap sourceBitmap, int matrixSize, bool applyBlue = true, bool applyGreen = true, bool applyRed = true ) { Bitmap resultBitmap = sourceBitmap.DilateAndErodeFilter( matrixSize, MorphologyType.Erosion, applyBlue, applyGreen, applyRed);
resultBitmap = resultBitmap.DilateAndErodeFilter( matrixSize, MorphologyType.Dilation, applyBlue, applyGreen, applyRed);
return resultBitmap; }
public static Bitmap CloseMorphologyFilter( this Bitmap sourceBitmap, int matrixSize, bool applyBlue = true, bool applyGreen = true, bool applyRed = true ) { Bitmap resultBitmap = sourceBitmap.DilateAndErodeFilter( matrixSize, MorphologyType.Dilation, applyBlue, applyGreen, applyRed);
resultBitmap = resultBitmap.DilateAndErodeFilter( matrixSize, MorphologyType.Erosion, applyBlue, applyGreen, applyRed);
return resultBitmap; }
Sample Images
The original source image used to create all of the sample images in this article has been licensed under the Creative Commons Attribution-Share Alike 3.0 Unported, 2.5 Generic, 2.0 Generic and 1.0 Generic license. The original image is attributed to Kenneth Dwain Harrelson and can be downloaded from Wikipedia.
The Original Image
Image Dilation 3×3 Blue
Image Dilation 3×3 Blue, Green
Image Dilation 3×3 Green
Image Dilation 3×3 Red
Image Dilation 3×3 Red, Blue
Image Dilation 3×3 Red, Green, Blue
Image Dilation 13×13 Blue
Image Erosion 3×3 Green, Blue
Image Erosion 3×3 Green
Image Erosion 3×3 Red
Image Erosion 3×3 Red, Blue
Image Erosion 3×3 Red, Green
Image Erosion 3×3 Red, Green, Blue
Image Erosion 9×9 Green
Image Erosion 9×9 Red
Image Open Morphology 11×11 Green
Image Open Morphology 11×11 Green Blue
Image Open Morphology 11×11 Red
Image Open Morphology 11×11 Red, Blue
Related Articles and Feedback
Feedback and questions are always encouraged. If you know of an alternative implementation or have ideas on a more efficient implementation please share in the comments section.
I’ve published a number of articles related to imaging and images of which you can find URL links here:
- C# How to: Image filtering by directly manipulating Pixel ARGB values
- C# How to: Image filtering implemented using a ColorMatrix
- C# How to: Blending Bitmap images using colour filters
- C# How to: Bitmap Colour Substitution implementing thresholds
- C# How to: Generating Icons from Images
- C# How to: Swapping Bitmap ARGB Colour Channels
- C# How to: Bitmap Pixel manipulation using LINQ Queries
- C# How to: Linq to Bitmaps – Partial Colour Inversion
- C# How to: Bitmap Colour Balance
- C# How to: Bi-tonal Bitmaps
- C# How to: Bitmap Colour Tint
- C# How to: Bitmap Colour Shading
- C# How to: Image Solarise
- C# How to: Image Contrast
- C# How to: Bitwise Bitmap Blending
- C# How to: Image Arithmetic
- C# How to: Image Convolution
- C# How to: Image Edge Detection
- C# How to: Difference Of Gaussians
- C# How to: Image Median Filter
- C# How to: Image Unsharp Mask
- C# How to: Image Colour Average
- C# How to: Morphological Edge Detection
- C# How to: Boolean Edge Detection
- C# How to: Gradient Based Edge Detection
- C# How to: Sharpen Edge Detection
- C# How to: Image Cartoon Effect
- C# How to: Calculating Gaussian Kernels
- C# How to: Image Blur
- C# How to: Image Transform Rotate
- C# How to: Image Transform Shear
- C# How to: Compass Edge Detection
- C# How to: Oil Painting and Cartoon Filter
- C# How to: Stained Glass Image Filter
Filed under: Augmented Reality, C#, Code Samples, Extension Methods, Graphic Filters, Graphics, How to, Image Convolution, Image Filters, Learn Everyday, Microsoft, Morphology Filters, New Version, Opensource, Tip Tagged: Augmented Reality, Bitmap ARGB, Bitmap Filters, Bitmap.LockBits, bitmapda, BitmapData, C#, Code Sample, Computer vision, Convolution filters, Convolution Kernel, Convolution matrix, Feature extraction, Graphic Filters, Image, Image processing, Image Transform, Machine vision, Matrix, Pixel Filters, Pixel Manipulation
