mirror of https://github.com/SixLabors/ImageSharp
8 changed files with 210 additions and 120 deletions
@ -0,0 +1,64 @@ |
|||||
|
// // Copyright (c) Six Labors and contributors.
|
||||
|
// // Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Primitives; |
||||
|
using SixLabors.Primitives; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies box blur processing to the image.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
internal class BoxBlurProcessor<TPixel> : ImageProcessor<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
private readonly BoxBlurProcessor definition; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="BoxBlurProcessor{TPixel}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="definition">The <see cref="BoxBlurProcessor"/> defining the processor parameters.</param>
|
||||
|
public BoxBlurProcessor(BoxBlurProcessor definition) |
||||
|
{ |
||||
|
this.definition = definition; |
||||
|
int kernelSize = (definition.Radius * 2) + 1; |
||||
|
this.KernelX = CreateBoxKernel(kernelSize); |
||||
|
this.KernelY = this.KernelX.Transpose(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the horizontal gradient operator.
|
||||
|
/// </summary>
|
||||
|
public DenseMatrix<float> KernelX { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the vertical gradient operator.
|
||||
|
/// </summary>
|
||||
|
public DenseMatrix<float> KernelY { get; } |
||||
|
|
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void OnFrameApply( |
||||
|
ImageFrame<TPixel> source, |
||||
|
Rectangle sourceRectangle, |
||||
|
Configuration configuration) => |
||||
|
new Convolution2PassProcessor<TPixel>(this.KernelX, this.KernelY, false).Apply( |
||||
|
source, |
||||
|
sourceRectangle, |
||||
|
configuration); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Create a 1 dimensional Box kernel.
|
||||
|
/// </summary>
|
||||
|
/// <param name="kernelSize">The maximum size of the kernel in either direction.</param>
|
||||
|
/// <returns>The <see cref="DenseMatrix{T}"/>.</returns>
|
||||
|
private static DenseMatrix<float> CreateBoxKernel(int kernelSize) |
||||
|
{ |
||||
|
var kernel = new DenseMatrix<float>(kernelSize, 1); |
||||
|
kernel.Fill(1F / kernelSize); |
||||
|
return kernel; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
// // Copyright (c) Six Labors and contributors.
|
||||
|
// // Licensed under the Apache License, Version 2.0.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
using SixLabors.ImageSharp.Primitives; |
||||
|
using SixLabors.Primitives; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Applies Gaussian blur processing to an image.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
internal class GaussianBlurProcessor<TPixel> : ImageProcessor<TPixel> |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
private readonly GaussianBlurProcessor definition; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="GaussianBlurProcessor{TPixel}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="definition">The <see cref="GaussianBlurProcessor"/> defining the processor parameters.</param>
|
||||
|
public GaussianBlurProcessor(GaussianBlurProcessor definition) |
||||
|
{ |
||||
|
this.definition = definition; |
||||
|
int kernelSize = (definition.Radius * 2) + 1; |
||||
|
this.KernelX = CreateGaussianKernel(kernelSize, definition.Sigma); |
||||
|
this.KernelY = this.KernelX.Transpose(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the horizontal gradient operator.
|
||||
|
/// </summary>
|
||||
|
public DenseMatrix<float> KernelX { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the vertical gradient operator.
|
||||
|
/// </summary>
|
||||
|
public DenseMatrix<float> KernelY { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override void OnFrameApply( |
||||
|
ImageFrame<TPixel> source, |
||||
|
Rectangle sourceRectangle, |
||||
|
Configuration configuration) => |
||||
|
new Convolution2PassProcessor<TPixel>(this.KernelX, this.KernelY, false).Apply( |
||||
|
source, |
||||
|
sourceRectangle, |
||||
|
configuration); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
|
||||
|
/// </summary>
|
||||
|
/// <returns>The <see cref="DenseMatrix{T}"/></returns>
|
||||
|
private static DenseMatrix<float> CreateGaussianKernel(int size, float weight) |
||||
|
{ |
||||
|
var kernel = new DenseMatrix<float>(size, 1); |
||||
|
|
||||
|
float sum = 0F; |
||||
|
float midpoint = (size - 1) / 2F; |
||||
|
|
||||
|
for (int i = 0; i < size; i++) |
||||
|
{ |
||||
|
float x = i - midpoint; |
||||
|
float gx = ImageMaths.Gaussian(x, weight); |
||||
|
sum += gx; |
||||
|
kernel[0, i] = gx; |
||||
|
} |
||||
|
|
||||
|
// Normalize kernel so that the sum of all weights equals 1
|
||||
|
for (int i = 0; i < size; i++) |
||||
|
{ |
||||
|
kernel[0, i] /= sum; |
||||
|
} |
||||
|
|
||||
|
return kernel; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue