Browse Source

luminance levels is now a parameter of the constructor, defaults to 65536

af/merge-core
popow 8 years ago
parent
commit
d5cc405212
  1. 6
      src/ImageSharp/Processing/Normalization/HistogramEqualizationExtension.cs
  2. 28
      src/ImageSharp/Processing/Normalization/HistogramEqualizationProcessor.cs
  3. 8
      tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs

6
src/ImageSharp/Processing/Normalization/HistogramEqualizationExtension.cs

@ -15,9 +15,11 @@ namespace SixLabors.ImageSharp.Processing.Normalization
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <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.Defaults to 65536.</param>
/// <returns>A histogram equalized grayscale image.</returns>
public static IImageProcessingContext<TPixel> HistogramEqualization<TPixel>(this IImageProcessingContext<TPixel> source)
public static IImageProcessingContext<TPixel> HistogramEqualization<TPixel>(this IImageProcessingContext<TPixel> source, int luminanceLevels = 65536)
where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new HistogramEqualizationProcessor<TPixel>());
=> source.ApplyProcessor(new HistogramEqualizationProcessor<TPixel>(luminanceLevels));
}
}

28
src/ImageSharp/Processing/Normalization/HistogramEqualizationProcessor.cs

@ -18,25 +18,39 @@ namespace SixLabors.ImageSharp.Processing.Normalization
internal class HistogramEqualizationProcessor<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// Initializes a new instance of the <see cref="HistogramEqualizationProcessor{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.Defaults to 65536.</param>
public HistogramEqualizationProcessor(int luminanceLevels = 65536)
{
Guard.MustBeGreaterThan(luminanceLevels, 0, nameof(luminanceLevels));
this.LuminanceLevels = luminanceLevels;
}
/// <summary>
/// Gets the luminance levels.
/// </summary>
public int LuminanceLevels { get; }
/// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{
MemoryAllocator memoryAllocator = configuration.MemoryAllocator;
int numberOfPixels = source.Width * source.Height;
bool is16bitPerChannel = typeof(TPixel) == typeof(Rgb48) || typeof(TPixel) == typeof(Rgba64);
Span<TPixel> pixels = source.GetPixelSpan();
// build the histogram of the grayscale levels
int luminanceLevels = is16bitPerChannel ? 65536 : 256;
using (IBuffer<int> histogramBuffer = memoryAllocator.AllocateClean<int>(luminanceLevels))
using (IBuffer<int> cdfBuffer = memoryAllocator.AllocateClean<int>(luminanceLevels))
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, luminanceLevels);
int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels);
histogram[luminance]++;
}
@ -50,7 +64,7 @@ namespace SixLabors.ImageSharp.Processing.Normalization
{
TPixel sourcePixel = pixels[i];
int luminance = this.GetLuminance(sourcePixel, luminanceLevels);
int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels);
double luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
pixels[i].PackFromVector4(new Vector4((float)luminanceEqualized));

8
tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs

@ -10,8 +10,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
{
public class HistogramEqualizationTests
{
[Fact]
public void HistogramEqualizationTest()
[Theory]
[InlineData(256)]
[InlineData(65536)]
public void HistogramEqualizationTest(int luminanceLevels)
{
// arrange
byte[] pixels = new byte[]
@ -48,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
};
// act
image.Mutate(x => x.HistogramEqualization());
image.Mutate(x => x.HistogramEqualization(luminanceLevels));
// assert
for (int y = 0; y < 8; y++)

Loading…
Cancel
Save