Gaussian Blur Filters

Gaussian Blur Kernel Filter

         Unlike common BlurBox image filters using a box or averaging filter, applies a simple average to the pixel values in a defined neighborhood. This results in a uniform and straightforward blurring effect, where each pixel contributes equally to its neighbors. On the other hand, Gaussian blur employs a Gaussian distribution to determine the weights of pixels in the neighborhood. This means that pixels closer to the center have higher weights, creating a smoother and more natural blurring effect. To emulate the Gaussian distribution, the following 3x3 matrix can be used:

// gaussian blur 3x3 kernel
{
  {1, 2, 1,},
  {2, 4, 2,},
  {1, 2, 1,},
};

         To preserve the luminosity of the source image, all elements are divided by 16, which represents the sum of the matrix elements.

// gaussian blur 3x3 kernel /16
double[,] customKernel = new double[,]
{
  { 0.0625, 0.125,  0.0625,},
  { 0.125,   0.25,   0.125,},
  { 0.0625, 0.125,  0.0625,},
};

         Gaussian blur tends to produce a more visually appealing and realistic result compared to the uniform blurring of common blur filters.

Original image
Gaussian blur
Original landscape image
Gaussian blur kernel filter
Gaussian blur kernel filter

C# code example

         The following C# code example illustrates the usage of the Aspose.Imaging .NET API. You can employ the `ConvolutionFilter` class, which offers predefined kernel filters such as GetGaussian() method with adjustable size and sigma value of Gauss distribution. Additionally, you have the flexibility to create your custom kernel matrix. In this example, image templates in PNG and SVG formats are loaded from the "templates" folder, and filters are applied from a predefined list.

using System;
using System.Collections.Generic;
using System.IO;
using Aspose.Imaging.ImageFilters.ComplexUtils;
using Aspose.Imaging.ImageFilters.Convolution;
using Aspose.Imaging.ImageFilters.FilterOptions;
const int Size = 5;
const double Sigma = 1.5, Angle = 45;
double[,] customKernel = GetRandomKernel(Size, 7, new Random());
Complex[,] customComplex = ConvolutionFilter.ToComplex(customKernel);
var kernelFilters = new FilterOptionsBase[]
{
// convolution filters
new ConvolutionFilterOptions(ConvolutionFilter.Emboss3x3),
new ConvolutionFilterOptions(ConvolutionFilter.Emboss5x5),
new ConvolutionFilterOptions(ConvolutionFilter.Sharpen3x3),
new ConvolutionFilterOptions(ConvolutionFilter.Sharpen5x5),
new ConvolutionFilterOptions(ConvolutionFilter.GetBlurBox(Size)),
new ConvolutionFilterOptions(ConvolutionFilter.GetBlurMotion(Size, Angle)),
new ConvolutionFilterOptions(ConvolutionFilter.GetGaussian(Size, Sigma)),
new ConvolutionFilterOptions(customKernel),
new GaussianBlurFilterOptions(Size, Sigma),
new SharpenFilterOptions(Size, Sigma),
new MedianFilterOptions(Size),
// deconvolution filters
new DeconvolutionFilterOptions(ConvolutionFilter.GetGaussian(Size, Sigma)),
new DeconvolutionFilterOptions(customKernel),
new DeconvolutionFilterOptions(customComplex),
new GaussWienerFilterOptions(Size, Sigma),
new MotionWienerFilterOptions(Size, Sigma, Angle),
};
var templatesFolder = @"c:\Users\USER\Downloads\templates\";
var dataDir = templatesFolder;
var inputPaths = new[]
{
Path.Combine(dataDir, "template.png"),
Path.Combine(dataDir, "template.svg"),
};
var outputs = new List<string>();
foreach (var inputPath in inputPaths)
{
for (int i = 0; i < kernelFilters.Length; i++)
{
var options = kernelFilters[i];
using (var image = Image.Load(inputPath))
{
var outputPath = $"{inputPath}-{i}.png";
if (image is RasterImage raster)
{
Filter(raster, options, outputPath);
}
else if (image is VectorImage vector)
{
var vectorAsPng = inputPath + ".png";
if (!File.Exists(vectorAsPng))
{
vector.Save(vectorAsPng);
outputs.Add(vectorAsPng);
}
using (var png = Image.Load(vectorAsPng))
{
Filter(png as RasterImage, options, outputPath);
}
}
}
}
}
outputs.ForEach(p => File.Delete(p));
static void Filter(RasterImage raster, FilterOptionsBase options, string outputPath)
{
raster.Filter(raster.Bounds, options);
raster.Save(outputPath);
}
static double[,] GetRandomKernel(int cols, int rows, Random random)
{
double[,] customKernel = new double[cols, rows];
for (int y = 0; y < customKernel.GetLength(0); y++)
{
for (int x = 0; x < customKernel.GetLength(1); x++)
{
customKernel[y, x] = random.NextDouble();
}
}
return customKernel;
}