Browse Source

Fix converting pixel to gray in histogram equalization

pull/1026/head
Brian Popow 7 years ago
parent
commit
7681c6a137
  1. 17
      src/ImageSharp/Common/Helpers/ImageMaths.cs
  2. 15
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  3. 4
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
  4. 11
      src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs

17
src/ImageSharp/Common/Helpers/ImageMaths.cs

@ -1,7 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.PixelFormats;
@ -14,6 +15,20 @@ namespace SixLabors.ImageSharp
/// </summary>
internal static class ImageMaths
{
/// <summary>
/// Vector for converting pixel to gray value as specified by ITU-R Recommendation BT.709.
/// </summary>
private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
/// <summary>
/// Convert a pixel value to grayscale using ITU-R Recommendation BT.709.
/// </summary>
/// <param name="vector">The vector to get the luminance from.</param>
/// <param name="luminanceLevels">The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
=> (int)MathF.Round(Vector4.Dot(vector, Bt709) * (luminanceLevels - 1));
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
/// </summary>

15
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -45,11 +45,6 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// </summary>
private readonly TgaCompression compression;
/// <summary>
/// Vector for converting pixel to gray value.
/// </summary>
private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
/// <summary>
/// Initializes a new instance of the <see cref="TgaEncoderCore"/> class.
/// </summary>
@ -347,15 +342,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
where TPixel : struct, IPixel<TPixel>
{
var vector = sourcePixel.ToVector4();
return GetLuminance(ref vector);
return ImageMaths.GetBT709Luminance(ref vector, 256);
}
/// <summary>
/// Convert the pixel values to grayscale using ITU-R Recommendation BT.709.
/// </summary>
/// <param name="vector">The vector to get the luminance from.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetLuminance(ref Vector4 vector)
=> (int)MathF.Round(Vector4.Dot(vector, Bt709) * (256 - 1));
}
}

4
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs

@ -349,7 +349,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
{
for (int idx = 0; idx < length; idx++)
{
int luminance = GetLuminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
int luminance = ImageMaths.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
Unsafe.Add(ref histogramBase, luminance)++;
}
}
@ -366,7 +366,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
{
for (int idx = 0; idx < length; idx++)
{
int luminance = GetLuminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
int luminance = ImageMaths.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
Unsafe.Add(ref histogramBase, luminance)--;
}
}

11
src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs

@ -143,16 +143,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
public static int GetLuminance(TPixel sourcePixel, int luminanceLevels)
{
var vector = sourcePixel.ToVector4();
return GetLuminance(ref vector, luminanceLevels);
return ImageMaths.GetBT709Luminance(ref vector, luminanceLevels);
}
/// <summary>
/// Convert the pixel values to grayscale using ITU-R Recommendation BT.709.
/// </summary>
/// <param name="vector">The vector to get the luminance from</param>
/// <param name="luminanceLevels">The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetLuminance(ref Vector4 vector, int luminanceLevels)
=> (int)MathF.Round(((.2126F * vector.X) + (.7152F * vector.Y) + (.0722F * vector.Y)) * (luminanceLevels - 1));
}
}

Loading…
Cancel
Save