Browse Source

using Vector4 to calculate the luminance and set the pixel value

pull/644/head
popow 8 years ago
parent
commit
ac69aa7bfd
  1. 39
      src/ImageSharp/Processing/Normalization/HistogramEqualizationProcessor.cs

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

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Numerics;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors; using SixLabors.ImageSharp.Processing.Processors;
@ -20,8 +21,6 @@ namespace SixLabors.ImageSharp.Processing.Normalization
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration) protected override void OnFrameApply(ImageFrame<TPixel> source, Rectangle sourceRectangle, Configuration configuration)
{ {
var rgb48 = default(Rgb48);
var rgb24 = default(Rgb24);
MemoryAllocator memoryAllocator = configuration.MemoryAllocator; MemoryAllocator memoryAllocator = configuration.MemoryAllocator;
int numberOfPixels = source.Width * source.Height; int numberOfPixels = source.Width * source.Height;
bool is16bitPerChannel = typeof(TPixel) == typeof(Rgb48) || typeof(TPixel) == typeof(Rgba64); bool is16bitPerChannel = typeof(TPixel) == typeof(Rgb48) || typeof(TPixel) == typeof(Rgba64);
@ -37,7 +36,7 @@ namespace SixLabors.ImageSharp.Processing.Normalization
for (int i = 0; i < pixels.Length; i++) for (int i = 0; i < pixels.Length; i++)
{ {
TPixel sourcePixel = pixels[i]; TPixel sourcePixel = pixels[i];
int luminance = this.GetLuminance(sourcePixel, is16bitPerChannel, ref rgb24, ref rgb48); int luminance = this.GetLuminance(sourcePixel, luminanceLevels);
histogram[luminance]++; histogram[luminance]++;
} }
@ -47,23 +46,14 @@ namespace SixLabors.ImageSharp.Processing.Normalization
// apply the cdf to each pixel of the image // apply the cdf to each pixel of the image
double numberOfPixelsMinusCdfMin = (double)(numberOfPixels - cdfMin); double numberOfPixelsMinusCdfMin = (double)(numberOfPixels - cdfMin);
int luminanceLevelsMinusOne = luminanceLevels - 1;
for (int i = 0; i < pixels.Length; i++) for (int i = 0; i < pixels.Length; i++)
{ {
TPixel sourcePixel = pixels[i]; TPixel sourcePixel = pixels[i];
int luminance = this.GetLuminance(sourcePixel, is16bitPerChannel, ref rgb24, ref rgb48); int luminance = this.GetLuminance(sourcePixel, luminanceLevels);
double luminanceEqualized = (cdf[luminance] / numberOfPixelsMinusCdfMin) * luminanceLevelsMinusOne; double luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
luminanceEqualized = Math.Round(luminanceEqualized);
if (is16bitPerChannel) pixels[i].PackFromVector4(new Vector4((float)luminanceEqualized));
{
pixels[i].PackFromRgb48(new Rgb48((ushort)luminanceEqualized, (ushort)luminanceEqualized, (ushort)luminanceEqualized));
}
else
{
pixels[i].PackFromRgba32(new Rgba32((byte)luminanceEqualized, (byte)luminanceEqualized, (byte)luminanceEqualized));
}
} }
} }
} }
@ -108,23 +98,12 @@ namespace SixLabors.ImageSharp.Processing.Normalization
/// Convert the pixel values to grayscale using ITU-R Recommendation BT.709. /// Convert the pixel values to grayscale using ITU-R Recommendation BT.709.
/// </summary> /// </summary>
/// <param name="sourcePixel">The pixel to get the luminance from</param> /// <param name="sourcePixel">The pixel to get the luminance from</param>
/// <param name="is16bitPerChannel">Flag indicates, if its 16 bits per channel, otherwise its 8</param> /// <param name="luminanceLevels">The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)</param>
/// <param name="rgb24">Will store the pixel values in case of 8 bit per channel</param> private int GetLuminance(TPixel sourcePixel, int luminanceLevels)
/// <param name="rgb48">Will store the pixel values in case of 16 bit per channel</param>
private int GetLuminance(TPixel sourcePixel, bool is16bitPerChannel, ref Rgb24 rgb24, ref Rgb48 rgb48)
{ {
// Convert to grayscale using ITU-R Recommendation BT.709 // Convert to grayscale using ITU-R Recommendation BT.709
int luminance; var vector = sourcePixel.ToVector4();
if (is16bitPerChannel) int luminance = Convert.ToInt32(((.2126F * vector.X) + (.7152F * vector.Y) + (.0722F * vector.Y)) * luminanceLevels);
{
sourcePixel.ToRgb48(ref rgb48);
luminance = Convert.ToInt32((.2126F * rgb48.R) + (.7152F * rgb48.G) + (.0722F * rgb48.B));
}
else
{
sourcePixel.ToRgb24(ref rgb24);
luminance = Convert.ToInt32((.2126F * rgb24.R) + (.7152F * rgb24.G) + (.0722F * rgb24.B));
}
return luminance; return luminance;
} }

Loading…
Cancel
Save