mirror of https://github.com/SixLabors/ImageSharp
7 changed files with 228 additions and 97 deletions
@ -0,0 +1,74 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Numerics; |
|||
using SixLabors.ImageSharp.Advanced; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
using SixLabors.Memory; |
|||
using SixLabors.Primitives; |
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Normalization |
|||
{ |
|||
/// <summary>
|
|||
/// Applies a global histogram equalization to the image.
|
|||
/// </summary>
|
|||
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|||
internal class GlobalHistogramEqualizationProcessor<TPixel> : HistogramEqualizationProcessor<TPixel> |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="GlobalHistogramEqualizationProcessor{TPixel}"/> class.
|
|||
/// </summary>
|
|||
/// <param name="luminanceLevels">The number of different luminance levels. Typical values are 256 for 8-bit grayscale images
|
|||
/// or 65536 for 16-bit grayscale images.</param>
|
|||
/// <param name="clipHistogram">Indicating whether to clip the histogram bins at a specific value.</param>
|
|||
/// <param name="clipLimit">The histogram clip limit. Histogram bins which exceed this limit, will be capped at this value.</param>
|
|||
public GlobalHistogramEqualizationProcessor(int luminanceLevels, bool clipHistogram, int clipLimit) |
|||
: base(luminanceLevels, clipHistogram, clipLimit) |
|||
{ |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) |
|||
{ |
|||
MemoryAllocator memoryAllocator = configuration.MemoryAllocator; |
|||
int numberOfPixels = source.Width * source.Height; |
|||
Span<TPixel> pixels = source.GetPixelSpan(); |
|||
|
|||
// Build the histogram of the grayscale levels.
|
|||
using (IBuffer<int> histogramBuffer = memoryAllocator.AllocateClean<int>(this.LuminanceLevels)) |
|||
using (IBuffer<int> cdfBuffer = memoryAllocator.AllocateClean<int>(this.LuminanceLevels)) |
|||
{ |
|||
Span<int> histogram = histogramBuffer.GetSpan(); |
|||
for (int i = 0; i < pixels.Length; i++) |
|||
{ |
|||
TPixel sourcePixel = pixels[i]; |
|||
int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); |
|||
histogram[luminance]++; |
|||
} |
|||
|
|||
if (this.ClipHistogramEnabled) |
|||
{ |
|||
this.ClipHistogram(histogram, this.ClipLimit); |
|||
} |
|||
|
|||
// Calculate the cumulative distribution function, which will map each input pixel to a new value.
|
|||
Span<int> cdf = cdfBuffer.GetSpan(); |
|||
int cdfMin = this.CalculateCdf(cdf, histogram); |
|||
|
|||
// Apply the cdf to each pixel of the image
|
|||
float numberOfPixelsMinusCdfMin = numberOfPixels - cdfMin; |
|||
for (int i = 0; i < pixels.Length; i++) |
|||
{ |
|||
TPixel sourcePixel = pixels[i]; |
|||
|
|||
int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); |
|||
float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin; |
|||
|
|||
pixels[i].PackFromVector4(new Vector4(luminanceEqualized)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,21 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Normalization |
|||
{ |
|||
/// <summary>
|
|||
/// Enumerates the different types of defined histogram equalization methods.
|
|||
/// </summary>
|
|||
public enum HistogramEqualizationMethod : int |
|||
{ |
|||
/// <summary>
|
|||
/// A global histogram equalization.
|
|||
/// </summary>
|
|||
Global, |
|||
|
|||
/// <summary>
|
|||
/// Adaptive histogram equalization.
|
|||
/// </summary>
|
|||
Adaptive |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// Copyright (c) Six Labors and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Processing.Processors.Normalization |
|||
{ |
|||
/// <summary>
|
|||
/// Data container providing the different options for the histogram equalization.
|
|||
/// </summary>
|
|||
public class HistogramEqualizationOptions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the histogram equalization method to use. Defaults to global histogram equalization.
|
|||
/// </summary>
|
|||
public HistogramEqualizationMethod Method { get; set; } = HistogramEqualizationMethod.Global; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of different luminance levels. Typical values are 256 for 8-bit grayscale images
|
|||
/// or 65536 for 16-bit grayscale images. Defaults to 256.
|
|||
/// </summary>
|
|||
public int LuminanceLevels { get; set; } = 256; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a value indicating whether to clip the histogram bins at a specific value. Defaults to true.
|
|||
/// </summary>
|
|||
public bool ClipHistogram { get; set; } = true; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the histogram clip limit. Histogram bins which exceed this limit, will be capped at this value.
|
|||
/// Defaults to 80.
|
|||
/// </summary>
|
|||
public int ClipLimit { get; set; } = 80; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the size of the grid for the adaptive histogram equalization. Defaults to 32.
|
|||
/// </summary>
|
|||
public int GridSize { get; set; } = 32; |
|||
} |
|||
} |
|||
Loading…
Reference in new issue