diff --git a/src/ImageSharp/Processing/HistogramEqualizationExtension.cs b/src/ImageSharp/Processing/HistogramEqualizationExtension.cs
index b472a2750..8dabfcc05 100644
--- a/src/ImageSharp/Processing/HistogramEqualizationExtension.cs
+++ b/src/ImageSharp/Processing/HistogramEqualizationExtension.cs
@@ -7,19 +7,29 @@ using SixLabors.ImageSharp.Processing.Processors.Normalization;
namespace SixLabors.ImageSharp.Processing
{
///
- /// Adds extension that allows applying an HistogramEqualization to the image.
+ /// Adds extension that allow the adjustment of the contrast of an image via its histogram.
///
public static class HistogramEqualizationExtension
{
+ ///
+ /// Equalizes the histogram of an image to increases the global contrast using 65536 luminance levels.
+ ///
+ /// The pixel format.
+ /// The image this method extends.
+ /// The .
+ public static IImageProcessingContext HistogramEqualization(this IImageProcessingContext source)
+ where TPixel : struct, IPixel
+ => HistogramEqualization(source, 65536);
+
///
/// Equalizes the histogram of an image to increases the global contrast.
///
/// The pixel format.
/// The image this method extends.
/// 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.
- /// A histogram equalized grayscale image.
- public static IImageProcessingContext HistogramEqualization(this IImageProcessingContext source, int luminanceLevels = 65536)
+ /// or 65536 for 16-bit grayscale images.
+ /// The .
+ public static IImageProcessingContext HistogramEqualization(this IImageProcessingContext source, int luminanceLevels)
where TPixel : struct, IPixel
=> source.ApplyProcessor(new HistogramEqualizationProcessor(luminanceLevels));
}
diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs
index fdd439a33..ba56e392f 100644
--- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs
+++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs
@@ -3,6 +3,7 @@
using System;
using System.Numerics;
+using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
@@ -21,8 +22,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// Initializes a new instance of the class.
///
/// 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.
- public HistogramEqualizationProcessor(int luminanceLevels = 65536)
+ /// or 65536 for 16-bit grayscale images.
+ public HistogramEqualizationProcessor(int luminanceLevels)
{
Guard.MustBeGreaterThan(luminanceLevels, 0, nameof(luminanceLevels));
@@ -30,7 +31,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
}
///
- /// Gets the luminance levels.
+ /// Gets the number of luminance levels.
///
public int LuminanceLevels { get; }
@@ -41,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
int numberOfPixels = source.Width * source.Height;
Span pixels = source.GetPixelSpan();
- // build the histogram of the grayscale levels
+ // Build the histogram of the grayscale levels.
using (IBuffer histogramBuffer = memoryAllocator.AllocateClean(this.LuminanceLevels))
using (IBuffer cdfBuffer = memoryAllocator.AllocateClean(this.LuminanceLevels))
{
@@ -53,33 +54,33 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
histogram[luminance]++;
}
- // calculate the cumulative distribution function, which will map each input pixel to a new value
+ // Calculate the cumulative distribution function, which will map each input pixel to a new value.
Span cdf = cdfBuffer.GetSpan();
- int cdfMin = this.CaluclateCdf(cdf, histogram);
+ int cdfMin = this.CalculateCdf(cdf, histogram);
- // apply the cdf to each pixel of the image
- double numberOfPixelsMinusCdfMin = (double)(numberOfPixels - cdfMin);
+ // 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);
- double luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
+ float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
- pixels[i].PackFromVector4(new Vector4((float)luminanceEqualized));
+ pixels[i].PackFromVector4(new Vector4(luminanceEqualized));
}
}
}
///
- /// Calculate the cumulative distribution function
+ /// Calculates the cumulative distribution function.
///
- /// The array holding the cdf
- /// The histogram of the input image
- /// The first none zero value of the cdf
- private int CaluclateCdf(Span cdf, Span histogram)
+ /// The array holding the cdf.
+ /// The histogram of the input image.
+ /// The first none zero value of the cdf.
+ private int CalculateCdf(Span cdf, Span histogram)
{
- // calculate the cumulative histogram
+ // Calculate the cumulative histogram
int histSum = 0;
for (int i = 0; i < histogram.Length; i++)
{
@@ -87,7 +88,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
cdf[i] = histSum;
}
- // get the first none zero value of the cumulative histogram
+ // Get the first none zero value of the cumulative histogram
int cdfMin = 0;
for (int i = 0; i < histogram.Length; i++)
{
@@ -98,7 +99,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
}
}
- // creating the lookup table: subtracting cdf min, so we do not need to do that inside the for loop
+ // Creating the lookup table: subtracting cdf min, so we do not need to do that inside the for loop
for (int i = 0; i < histogram.Length; i++)
{
cdf[i] = Math.Max(0, cdf[i] - cdfMin);
@@ -112,6 +113,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
///
/// The pixel to get the luminance from
/// The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)
+ [MethodImpl(InliningOptions.ShortMethod)]
private int GetLuminance(TPixel sourcePixel, int luminanceLevels)
{
// Convert to grayscale using ITU-R Recommendation BT.709
diff --git a/tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs b/tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs
index ebecfec5a..1595ed32c 100644
--- a/tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs
+++ b/tests/ImageSharp.Tests/Processing/Normalization/HistogramEqualizationTests.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
[InlineData(65536)]
public void HistogramEqualizationTest(int luminanceLevels)
{
- // arrange
+ // Arrange
byte[] pixels = new byte[]
{
52, 55, 61, 59, 70, 61, 76, 61,
@@ -26,6 +26,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
69, 85, 64, 58, 55, 61, 65, 83,
70, 87, 69, 68, 65, 73, 78, 90
};
+
var image = new Image(8, 8);
for (int y = 0; y < 8; y++)
{
@@ -48,10 +49,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Normalization
146, 206, 130, 117, 85, 166, 182, 215
};
- // act
+ // Act
image.Mutate(x => x.HistogramEqualization(luminanceLevels));
- // assert
+ // Assert
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 8; x++)