Browse Source

Add box blur. Fix #263

Former-commit-id: f8adc1e633f948b24cee0113681133b075603183
Former-commit-id: 1917069ba119db6ecddc34581c258e050ab40e3d
Former-commit-id: 4d1a9fefc9f2767a66fc236ddb25d14b3c600c9f
af/merge-core
James Jackson-South 10 years ago
parent
commit
e4cd645e92
  1. 106
      src/ImageProcessor/Filters/Convolution/BoxBlur.cs
  2. 4
      src/ImageProcessor/Filters/Convolution/GuassianBlur.cs
  3. 75
      src/ImageProcessor/Filters/ImageFilterExtensions.cs
  4. 3
      tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

106
src/ImageProcessor/Filters/Convolution/BoxBlur.cs

@ -0,0 +1,106 @@
// <copyright file="BoxBlur.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessor.Filters
{
/// <summary>
/// Applies a Box blur filter to the image.
/// </summary>
public class BoxBlur : Convolution2PassFilter
{
/// <summary>
/// The maximum size of the kernal in either direction.
/// </summary>
private readonly int kernelSize;
/// <summary>
/// The vertical kernel
/// </summary>
private float[,] kernelY;
/// <summary>
/// The horizontal kernel
/// </summary>
private float[,] kernelX;
/// <summary>
/// Initializes a new instance of the <see cref="GuassianBlur"/> class.
/// </summary>
/// <param name="radius">
/// The 'radius' value representing the size of the area to sample.
/// </param>
public BoxBlur(int radius = 7)
{
this.kernelSize = (radius * 2) + 1;
}
/// <inheritdoc/>
public override float[,] KernelX => this.kernelX;
/// <inheritdoc/>
public override float[,] KernelY => this.kernelY;
/// <inheritdoc/>
public override int Parallelism => 1;
/// <inheritdoc/>
protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
{
if (this.kernelY == null)
{
this.kernelY = this.CreateBoxKernel(false);
}
if (this.kernelX == null)
{
this.kernelX = this.CreateBoxKernel(true);
}
}
/// <summary>
/// Create a 1 dimensional Box kernel.
/// </summary>
/// <param name="horizontal">Whether to calculate a horizontal kernel.</param>
/// <returns>The <see cref="T:float[,]"/></returns>
private float[,] CreateBoxKernel(bool horizontal)
{
int size = this.kernelSize;
float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
float sum = 0.0f;
for (int i = 0; i < size; i++)
{
float x = 1;
sum += x;
if (horizontal)
{
kernel[0, i] = x;
}
else
{
kernel[i, 0] = x;
}
}
// Normalise kernel so that the sum of all weights equals 1
if (horizontal)
{
for (int i = 0; i < size; i++)
{
kernel[0, i] = kernel[0, i] / sum;
}
}
else
{
for (int i = 0; i < size; i++)
{
kernel[i, 0] = kernel[i, 0] / sum;
}
}
return kernel;
}
}
}

4
src/ImageProcessor/Filters/Convolution/GuassianBlur.cs

@ -35,9 +35,7 @@ namespace ImageProcessor.Filters
/// <summary>
/// Initializes a new instance of the <see cref="GuassianBlur"/> class.
/// </summary>
/// <param name="sigma">
/// The 'sigma' value representing the weight of the blur.
/// </param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
public GuassianBlur(float sigma = 3f)
{
this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1;

75
src/ImageProcessor/Filters/ImageFilterExtensions.cs

@ -96,6 +96,31 @@ namespace ImageProcessor.Filters
return source.Process(rectangle, new BlackWhite());
}
/// <summary>
/// Applies a box blur to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image BoxBlur(this Image source, int radius = 7)
{
return BoxBlur(source, radius, source.Bounds);
}
/// <summary>
/// Applies a box blur to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image BoxBlur(this Image source, int radius, Rectangle rectangle)
{
return source.Process(rectangle, new BoxBlur(radius));
}
/// <summary>
/// Alters the brightness component of the image.
/// </summary>
@ -209,6 +234,56 @@ namespace ImageProcessor.Filters
: source.Process(rectangle, new GreyscaleBt601());
}
/// <summary>
/// Applies a Guassian blur to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image GuassianBlur(this Image source, float sigma = 3f)
{
return GuassianBlur(source, sigma, source.Bounds);
}
/// <summary>
/// Applies a Guassian blur to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle)
{
return source.Process(rectangle, new GuassianBlur(sigma));
}
/// <summary>
/// Applies a Guassian sharpening filter to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image GuassianSharpen(this Image source, float sigma = 3f)
{
return GuassianSharpen(source, sigma, source.Bounds);
}
/// <summary>
/// Applies a Guassian sharpening filter to the image.
/// </summary>
/// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle)
{
return source.Process(rectangle, new GuassianSharpen(sigma));
}
/// <summary>
/// Alters the hue component of the image.
/// </summary>

3
tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs

@ -43,7 +43,8 @@ namespace ImageProcessor.Tests
{ "GuassianBlur", new GuassianBlur(10) },
{ "GuassianSharpen", new GuassianSharpen(10) },
{ "Hue-180", new Hue(180) },
{ "Hue--180", new Hue(-180) }
{ "Hue--180", new Hue(-180) },
{ "BoxBlur", new BoxBlur(10) },
};
[Theory]

Loading…
Cancel
Save