Edge Detection Filters
Edge Detection Custom Kernel Filter
The custom kernel filter for edge detection shares similarities with the Sharpen filter but with a notable distinction: the total sum of matrix elements equals zero. Consequently, the resulting image appears almost black, except for pixels that deviate from their neighbors. These pixels typically reside at the boundaries between distinct areas or edges.
In this example, the central pixel value is compared to its surrounding pixels. It is possible to define a custom kernel to specifically identify edges in either horizontal or vertical directions.
// edge detection kernel
double[,] customKernel = new double[,]
{
{ -1, -1, -1,}
{ -1, 8, -1,},
{ -1, -1, -1,},
}
Ultimately, applying the filter results in retaining only the contours of the image against a black background.


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, as well as 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; | |
} |