mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 2b6e609568974428a5bb5e499037b9662fe2f25a Former-commit-id: 1fa30277428dd05091968ee42f6f5db057b193fb Former-commit-id: cadfaf22b1424a734ae9dfc755ad1ac28380f4a8af/merge-core
4 changed files with 157 additions and 2 deletions
@ -0,0 +1,153 @@ |
|||
// <copyright file="GuassianSharpen.cs" company="James South">
|
|||
// Copyright (c) James South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessor.Filters |
|||
{ |
|||
using System; |
|||
|
|||
/// <summary>
|
|||
/// Applies a Gaussian sharpening filter to the image.
|
|||
/// </summary>
|
|||
public class GuassianSharpen : Convolution2PassFilter |
|||
{ |
|||
/// <summary>
|
|||
/// The maximum size of the kernal in either direction.
|
|||
/// </summary>
|
|||
private readonly int kernelSize; |
|||
|
|||
/// <summary>
|
|||
/// The spread of the blur.
|
|||
/// </summary>
|
|||
private readonly float sigma; |
|||
|
|||
/// <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="GuassianSharpen"/> class.
|
|||
/// </summary>
|
|||
/// <param name="sigma">
|
|||
/// The 'sigma' value representing the weight of the sharpening.
|
|||
/// </param>
|
|||
public GuassianSharpen(float sigma = 3f) |
|||
{ |
|||
this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; |
|||
this.sigma = sigma; |
|||
} |
|||
|
|||
/// <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(Rectangle targetRectangle, Rectangle sourceRectangle) |
|||
{ |
|||
if (this.kernelY == null) |
|||
{ |
|||
this.kernelY = this.CreateGaussianKernel(false); |
|||
} |
|||
|
|||
if (this.kernelX == null) |
|||
{ |
|||
this.kernelX = this.CreateGaussianKernel(true); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
|
|||
/// </summary>
|
|||
/// <param name="horizontal">Whether to calculate a horizontal kernel.</param>
|
|||
/// <returns>The <see cref="T:float[,]"/></returns>
|
|||
private float[,] CreateGaussianKernel(bool horizontal) |
|||
{ |
|||
int size = this.kernelSize; |
|||
float weight = this.sigma; |
|||
float[,] kernel = horizontal ? new float[1, size] : new float[size, 1]; |
|||
float sum = 0; |
|||
|
|||
float midpoint = (size - 1) / 2f; |
|||
for (int i = 0; i < size; i++) |
|||
{ |
|||
float x = i - midpoint; |
|||
float gx = ImageMaths.Gaussian(x, weight); |
|||
sum += gx; |
|||
if (horizontal) |
|||
{ |
|||
kernel[0, i] = gx; |
|||
} |
|||
else |
|||
{ |
|||
kernel[i, 0] = gx; |
|||
} |
|||
} |
|||
|
|||
// Invert the kernel for sharpening.
|
|||
int midpointRounded = (int)midpoint; |
|||
|
|||
if (horizontal) |
|||
{ |
|||
for (int i = 0; i < size; i++) |
|||
{ |
|||
if (i == midpointRounded) |
|||
{ |
|||
// Calculate central value
|
|||
kernel[0, i] = (2f * sum) - kernel[0, i]; |
|||
} |
|||
else |
|||
{ |
|||
// invert value
|
|||
kernel[0, i] = -kernel[0, i]; |
|||
} |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
for (int i = 0; i < size; i++) |
|||
{ |
|||
if (i == midpointRounded) |
|||
{ |
|||
// Calculate central value
|
|||
kernel[i, 0] = (2 * sum) - kernel[i, 0]; |
|||
} |
|||
else |
|||
{ |
|||
// invert value
|
|||
kernel[i, 0] = -kernel[i, 0]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
// 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; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue