mirror of https://github.com/SixLabors/ImageSharp
7 changed files with 180 additions and 141 deletions
@ -1,50 +1,46 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.ImageSharp.Processing.Processors.Convolution; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing |
|||
{ |
|||
/// <summary>
|
|||
/// Adds Gaussian sharpening extensions to the <see cref="Image{TPixel}"/> type.
|
|||
/// Adds Gaussian sharpening extensions to the <see cref="Image"/> type.
|
|||
/// </summary>
|
|||
public static class GaussianSharpenExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a Gaussian sharpening filter to the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <param name="source">The image this method extends.</param>
|
|||
/// <returns>The <see cref="Image{TPixel}"/>.</returns>
|
|||
public static IImageProcessingContext<TPixel> GaussianSharpen<TPixel>(this IImageProcessingContext<TPixel> source) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>()); |
|||
public static IImageProcessingContext GaussianSharpen(this IImageProcessingContext source) => |
|||
source.ApplyProcessor(new GaussianSharpenProcessor()); |
|||
|
|||
/// <summary>
|
|||
/// Applies a Gaussian sharpening filter to the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <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{TPixel}"/>.</returns>
|
|||
public static IImageProcessingContext<TPixel> GaussianSharpen<TPixel>(this IImageProcessingContext<TPixel> source, float sigma) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>(sigma)); |
|||
public static IImageProcessingContext GaussianSharpen(this IImageProcessingContext source, float sigma) => |
|||
source.ApplyProcessor(new GaussianSharpenProcessor(sigma)); |
|||
|
|||
/// <summary>
|
|||
/// Applies a Gaussian sharpening filter to the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
/// <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{TPixel}"/>.</returns>
|
|||
public static IImageProcessingContext<TPixel> GaussianSharpen<TPixel>(this IImageProcessingContext<TPixel> source, float sigma, Rectangle rectangle) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
=> source.ApplyProcessor(new GaussianSharpenProcessor<TPixel>(sigma), rectangle); |
|||
public static IImageProcessingContext GaussianSharpen( |
|||
this IImageProcessingContext source, |
|||
float sigma, |
|||
Rectangle rectangle) => |
|||
source.ApplyProcessor(new GaussianSharpenProcessor(sigma), rectangle); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,93 @@ |
|||
// // Copyright (c) Six Labors and contributors.
|
|||
// // Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
using SixLabors.ImageSharp.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Convolution |
|||
{ |
|||
internal static class ConvolutionProcessorHelpers |
|||
{ |
|||
/// <summary>
|
|||
/// Kernel radius is calculated using the minimum viable value.
|
|||
/// <see cref="http://chemaguerra.com/gaussian-filter-radius/"/>.
|
|||
/// </summary>
|
|||
internal static int GetDefaultGaussianRadius(float sigma) |
|||
{ |
|||
return (int)MathF.Ceiling(sigma * 3); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="DenseMatrix{T}"/>.</returns>
|
|||
internal static DenseMatrix<float> CreateGaussianBlurKernel(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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
|
|||
/// </summary>
|
|||
/// <returns>The <see cref="DenseMatrix{T}"/>.</returns>
|
|||
internal static DenseMatrix<float> CreateGaussianSharpenKernel(int size, float weight) |
|||
{ |
|||
var kernel = new DenseMatrix<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; |
|||
kernel[0, i] = gx; |
|||
} |
|||
|
|||
// Invert the kernel for sharpening.
|
|||
int midpointRounded = (int)midpoint; |
|||
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]; |
|||
} |
|||
} |
|||
|
|||
// Normalize kernel so that the sum of all weights equals 1
|
|||
for (int i = 0; i < size; i++) |
|||
{ |
|||
kernel[0, i] /= sum; |
|||
} |
|||
|
|||
return kernel; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
// 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 sharpening processing to the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GaussianSharpenProcessor<TPixel> : ImageProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GaussianSharpenProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="definition">The <see cref="GaussianBlurProcessor"/> defining the processor parameters.</param>
|
|||
public GaussianSharpenProcessor(GaussianSharpenProcessor definition) |
|||
{ |
|||
int kernelSize = (definition.Radius * 2) + 1; |
|||
this.KernelX = ConvolutionProcessorHelpers.CreateGaussianSharpenKernel(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); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue