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