Motion Blur Filters

Motion Blur Custom Kernel Filter

         You have the option to design a custom kernel with elements positioned, for instance, exclusively along one diagonal. In such a scenario, the pixel value is determined by the weighted average of these pixels, producing the 'Motion Blur' image effect. Higher element weights contribute more to the final pixel value in the Motion Blur image effect. Maintaining a total sum of elements equal to 1 preserves the original picture's brightness. The flexibility to place elements in various directions allows for the creation of different movement effects in the image.

// custom MotionBlur 5x5 kernel
double[,] customKernel = new double[,]
{
  { 0.25, 0,   0,   0,   0    },
  { 0,    0.2, 0,   0,   0    },
  { 0,    0,   0.1, 0,   0    },
  { 0,    0,   0,   0.2, 0    },
  { 0,    0,   0,    0,  0.25 },
};

         This effect simulates the appearance of camera movement during photo capture in a diagonal direction, creating the illusion of motion in the image.

Original image
MotionBlur filter
Original vector image
Custom Motion blur 7x7 horizontal kernel filter in Python
Custom MotionBlur kernel filter

C# code example

         The following C# code example shows the usage of the Aspose.Imaging .NET API. You can employ the `ConvolutionFilter` class, which offers predefined kernel filters GetBlurMotion() with adjustable size and angle settings. 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;
}