C# How to: Calculating Gaussian Kernels

Article Purpose

This article’s purpose is to explain and illustrate in detail the requirements involved in calculating intended for use in when implementing filters. This article’s discussion spans from exploring concepts in theory and continues on to implement concepts through C# sample source code.

Ant: Gaussian Kernel 5×5 Weight 19

Ant Gaussian Kernel 5x5 Weight 19

Sample Source Code

This article is accompanied by a sample source code Visual Studio project which is available for download

Using the Sample Application

A Sample Application forms part of the accompanying sample source code, intended to implement the topics discussed and also provides the means to replicate and test the concepts being illustrated.

The sample application is a based application which provides functionality enabling users to generate/calculate  . Calculation results are influenced through user specified options in the form of: Kernel Size and Weight.

Ladybird: Gaussian Kernel 5×5 Weight 5.5

Gaussian Kernel 5x5 Weight 5.5

In the sample application and related sample source code when referring to Kernel Size, a reference is being made relating to the physical size dimensions of the / used in . When higher values are specified in setting the Kernel Size the resulting output will reflect a greater degree of . Kernel Sizes being specified as lower values result in result reflecting a lesser degree of .

In a similar fashion to the Kernel size value, the Weight value provided when generating a results in smoother/more blurred when specified as higher values. Lower values assigned to the Weight value has the expected result of less being evident in output .

Prey Mantis: Gaussian Kernel 13×13 Weight 13

Prey Mantis Gaussian Kernel 13x13 Weight 13

The sample application has the ability to provide the user with a visual representation implementing the calculated value . Users are able to select source/input from the local system by clicking the Load Image button. When desired users are able to save blurred/filtered to the local file system by clicking the Save Image button.

The image below is screenshot of the Gaussian Kernel Calculator sample application in action:

Gaussian Kernel Calculator Sample Application

Calculating Gaussian Convolution Kernels

The formula implemented in calculating can be implemented in C# source code fairly easily. Once the method in which the formula operates has been grasped the actual code implementation becomes straight forward.

The formula can be expressed as follows:

Gaussian Kernel formula

The formula contains a number of symbols, which define how the filter will be implemented. The symbols forming part of the formula are described in the following list:

  • G(x y) – A value calculated using the formula. This value forms part of a , representing a single element.
  • π – Pi, one of the better known members of the Greek alphabet. The mathematical constant defined as 22 / 7.
  • σ – The lower case version of the Greek alphabet letter Sigma. This symbol simply represents a threshold or factor value, as specified by the user.
  • e – The formula references a lower case e symbol. The symbol represents . The value of has been defined as a mathematical constant equating to 2.71828182846.
  • x, y – The variables referenced as x and y relate to pixel coordinates within an . y Representing the vertical offset or row and x represents the horizontal offset or column.

Note: The formula’s implementation expects x and y to equal zero values when representing the coordinates of the pixel located in the middle of the .

Ladybird: Gaussian Kernel 13×13 Weight 9.5

Gaussian Kernel 13x13 Weight 9.5 

When calculating the elements, the coordinate values expressed by x and y should reflect the distance in pixels from the middle pixel. All coordinate values must be greater than zero.

In order to gain a better grasp on the formula we can implement the formula in steps. If we were to create a 3×3 and specified a weighting value of 5.5 our calculations can start off as indicated by the following illustration:

Gaussian Kernel Formula

The formula has been implement on each element forming part of the , 9 values in total. Coordinate values have now been replaced with actual values, differing for each position/element. Calculating zero to the power of two equates to zero. In the scenario above indicating zeros which express exponential values might help to ease initial understanding, as opposed to providing simplified values and potentially causing confusing scenarios. The following image illustrates the calculated values of each element:

Gaussian Kernel Values non summed

Ant: Gaussian Kernel 9×9 Weight 19

Ant Gaussian Kernel 9x9 Weight 19

An important requirement to remember at this point being that the sum total of all the elements contained as part of a / must equate to one. Looking at our calculated results that is not the case. The needs to be modified in order to satisfy the requirement of having a sum total value of 1 when adding together all the elements of the .

At this point the sum total of the equates to 0.046322548968. We can correct the values, ensuring the sum total of all elements equate to 1. The values should be updated by multiplying each element by the one divided by the current sum. In other words each item should be multiplied by:

1.0 / 0.046322548968

After updating the by multiplying each element with the the values mentioned above the result as follows:

Calculated Gaussian Kernel Values

We have now successfully calculated a 3×3 which implements a weight value of 5.5. Implementing the has the following effect:

Rose: Gaussian Kernel 3×3 Weight 5.5

Rose Gaussian Kernel 3x3 Weight 5.5

The Original Image

Rose_Amber_Flush_20070601

The calculated can now be implemented when performing .

Implementing Gaussian Kernel Calculations

In this section of the article we will be exploring how to implement kernel calculations in terms of C# code. Defined as part of the sample source code the of the static MatrixCalculator class, exposing the static Calculate method. All of the formula calculation tasks discussed in the previous section have been implemented within this function.

As parameter values the method expects a value indicating the size and a value representing the Weight value. The Calculate method returns a two dimensional array of type double. The return value array represents the calculated .

The definition of the MatrixCalculator.Calculate method as follows:

public static double[,] Calculate(int length, double weight) 
{
    double[,] Kernel = new double [length, lenght]; 
    double sumTotal = 0; 

int kernelRadius = lenght / 2; double distance = 0;
double calculatedEuler = 1.0 / (2.0 * Math.PI * Math.Pow(weight, 2));
for (int filterY = -kernelRadius; filterY <= kernelRadius; filterY++) { for (int filterX = -kernelRadius; filterX <= kernelRadius; filterX++) { distance = ((filterX * filterX) + (filterY * filterY)) / (2 * (weight * weight));
Kernel[filterY + kernelRadius, filterX + kernelRadius] = calculatedEuler * Math.Exp(-distance);
sumTotal += Kernel[filterY + kernelRadius, filterX + kernelRadius]; } }
for (int y = 0; y < lenght; y++) { for (int x = 0; x < lenght; x++) { Kernel[y, x] = Kernel[y, x] * (1.0 / sumTotal); } }
return Kernel; }

Ladybird: Gaussian Kernel 19×19 Weight 9.5

Gaussian Kernel 19x19 Weight 9.5

The sample source code provides the definition of the ConvolutionFilter , targeting the class. This method accepts as a parameter a two dimensional array representing the to implement when performing . The value passed to this function originates from the calculated .

Detailed below is the definition of the ConvolutionFilter :

public static Bitmap ConvolutionFilter(this Bitmap sourceBitmap,  
                                         double[,] filterMatrix,  
                                              double factor = 1,  
                                                   int bias = 0)  
{ 
    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);
double blue = 0.0; double green = 0.0; double red = 0.0;
int filterWidth = filterMatrix.GetLength(1); int filterHeight = filterMatrix.GetLength(0);
int filterOffset = (filterWidth-1) / 2; int calcOffset = 0;
int byteOffset = 0;
for (int offsetY = filterOffset; offsetY < sourceBitmap.Height - filterOffset; offsetY++) { for (int offsetX = filterOffset; offsetX < sourceBitmap.Width - filterOffset; offsetX++) { blue = 0; green = 0; red = 0;
byteOffset = offsetY * sourceData.Stride + offsetX * 4;
for (int filterY = -filterOffset; filterY <= filterOffset; filterY++) { for (int filterX = -filterOffset; filterX <= filterOffset; filterX++) {
calcOffset = byteOffset + (filterX * 4) + (filterY * sourceData.Stride);
blue += (double )(pixelBuffer[calcOffset]) * filterMatrix[filterY + filterOffset, filterX + filterOffset];
green += (double )(pixelBuffer[calcOffset + 1]) * filterMatrix[filterY + filterOffset, filterX + filterOffset];
red += (double )(pixelBuffer[calcOffset + 2]) * filterMatrix[filterY + filterOffset, filterX + filterOffset]; } }
blue = factor * blue + bias; green = factor * green + bias; red = factor * red + bias;
blue = (blue > 255 ? 255 : (blue < 0 ? 0 : blue)); green = (green > 255 ? 255 : (green < 0 ? 0 : green)); red = (red > 255 ? 255 : (red < 0 ? 0 : blue));
resultBuffer[byteOffset] = (byte)(blue); resultBuffer[byteOffset + 1] = (byte)(green); resultBuffer[byteOffset + 2] = (byte)(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; }

Ant: Gaussian Kernel 7×7 Weight 19

Ant Gaussian Kernel 7x7 Weight 19

Sample

This article features a number of sample images. All featured images have been licensed allowing for reproduction.

The sample images featuring an image of a prey mantis is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license and can be downloaded from .

The sample images featuring an image of an ant has been released into the public domain by its author, Sean.hoyland. This applies worldwide. In some countries this may not be legally possible; if so: Sean.hoyland grants anyone the right to use this work for any purpose, without any conditions, unless such conditions are required by law. The original image can be downloaded from .

The sample images featuring an image of a ladybird (ladybug or lady beetle) is licensed under the Creative Commons Attribution-Share Alike 2.0 Generic license and can be downloaded from Wikipedia.

The sample images featuring an image of a wasp is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license and can be downloaded from Wikimedia.org.

The Original Image

1280px-Gemeiner_Widderbock_4483 

Wasp Gaussian Kernel 3×3 Weight 9.25

Wasp Gaussian Kernel 3x3 Weight 9.25

Wasp Gaussian Kernel 5×5 Weight 9.25

Wasp Gaussian Kernel 5x5 Weight 9.25

Wasp Gaussian Kernel 7×7 Weight 9.25

Wasp Gaussian Kernel 7x7 Weight 9.25

Wasp Gaussian Kernel 9×9 Weight 9.25

Wasp Gaussian Kernel 9x9 Weight 9.25

Wasp Gaussian Kernel 11×11 Weight 9.25

Wasp Gaussian Kernel 11x11 Weight 9.25

Wasp Gaussian Kernel 13×13 Weight 9.25

Wasp Gaussian Kernel 13x13 Weight 9.25

Wasp Gaussian Kernel 15×15 Weight 9.25

Wasp Gaussian Kernel 15x15 Weight 9.25

Wasp Gaussian Kernel 17×17 Weight 9.25

Wasp Gaussian Kernel 17x17 Weight 9.25

Wasp Gaussian Kernel 19×19 Weight 9.25

Wasp Gaussian Kernel 19x19 Weight 9.25

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:

27 Responses to “C# How to: Calculating Gaussian Kernels”



  1. 1 C# How to: Image Blur | Software by Default Trackback on June 9, 2013 at 10:20 PM
  2. 2 C# How to: Image Transform Rotate | Software by Default Trackback on June 16, 2013 at 10:40 AM
  3. 3 C# How to: Image Transform Shear | Software by Default Trackback on June 16, 2013 at 5:45 PM
  4. 4 C# How to: Compass Edge Detection | Software by Default Trackback on June 22, 2013 at 9:35 PM
  5. 5 C# How to: Oil Painting and Cartoon Filter | Software by Default Trackback on June 30, 2013 at 10:48 AM
  6. 6 C# How to: Stained Glass Image Filter | Software by Default Trackback on June 30, 2013 at 10:50 AM
  7. 7 C# How to: Image Cartoon Effect | Software by Default Trackback on June 30, 2013 at 1:45 PM
  8. 8 C# How to: Boolean Edge Detection | Software by Default Trackback on June 30, 2013 at 1:56 PM
  9. 9 C# How to: Morphological Edge Detection | Software by Default Trackback on June 30, 2013 at 2:02 PM
  10. 10 C# How to: Image Erosion and Dilation | Software by Default Trackback on June 30, 2013 at 2:11 PM
  11. 11 C# How to: Image Colour Average | Software by Default Trackback on June 30, 2013 at 2:20 PM
  12. 12 C# How to: Image Unsharp Mask | Software by Default Trackback on June 30, 2013 at 2:28 PM
  13. 13 C# How to: Image Median Filter | Software by Default Trackback on June 30, 2013 at 3:16 PM
  14. 14 C# How to: Difference Of Gaussians | Software by Default Trackback on June 30, 2013 at 3:28 PM
  15. 15 C# How to: Image Edge Detection | Software by Default Trackback on June 30, 2013 at 3:33 PM
  16. 16 C# How to: Image Convolution | Software by Default Trackback on June 30, 2013 at 3:55 PM
  17. 17 C# How to: Generate a Web Service from WSDL | Software by Default Trackback on June 30, 2013 at 4:08 PM
  18. 18 C# How to: Decoding/Converting Base64 strings to Bitmap images | Software by Default Trackback on June 30, 2013 at 4:14 PM
  19. 19 C# How to: Bitmap Colour Substitution implementing thresholds | Software by Default Trackback on July 6, 2013 at 4:33 PM
  20. 20 C# How to: Swapping Bitmap ARGB Colour Channels | Software by Default Trackback on July 6, 2013 at 5:02 PM
  21. 21 C# How to: Image filtering by directly manipulating Pixel ARGB values | Software by Default Trackback on July 8, 2013 at 2:58 AM
  22. 22 C# How to: Image ASCII Art | Software by Default Trackback on July 14, 2013 at 7:23 AM
  23. 23 C# How to: Weighted Difference of Gaussians | Software by Default Trackback on July 14, 2013 at 8:12 PM
  24. 24 C# How to: Image Boundary Extraction | Software by Default Trackback on July 21, 2013 at 10:24 AM
  25. 25 C# How to: Image Abstract Colours Filter | Software by Default Trackback on July 28, 2013 at 7:41 PM
  26. 26 C# How to: Fuzzy Blur Filter | Software by Default Trackback on August 9, 2013 at 6:39 AM
  27. 27 C# How to: Image Distortion Blur | Software by Default Trackback on August 9, 2013 at 10:13 PM

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




about.me :: Dewald Esterhuizen

Dewald Esterhuizen

Blog Stats

  • 170,696 hits

Gravatar :: Dewald Esterhuizen

SoftwareByDefault QR Code

SoftwareByDefault QR Code

I review for the O'Reilly Blogger Review Program

Enter your email address to follow and receive notifications of new posts by email.

Join 152 other followers

Archives

Twitter feed

RSS SoftwareByDefault on MSDN

  • An error has occurred; the feed is probably down. Try again later.

del.icio.us Links

http://softwarebydefault.com
http://softwarebydefault.com
http://softwarebydefault.com
http://softwarebydefault.com
http://softwarebydefault.com

Follow

Get every new post delivered to your Inbox.

Join 152 other followers

%d bloggers like this: