Browse Source

alpha channel from the original image is now preserved

pull/673/head
popow 8 years ago
parent
commit
fa1f036720
  1. 10
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs
  2. 9
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor.cs
  3. 2
      src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs
  4. 2
      src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs
  5. 8
      src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs

10
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// <param name="luminanceLevels">The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// <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> /// 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="clipHistogram">Indicating whether to clip the histogram bins at a specific value.</param>
/// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the grid. Histogram bins which exceed this limit, will be capped at this value.</param> /// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value.</param>
/// <param name="tiles">The number of tiles the image is split into (horizontal and vertically). Minimum value is 2.</param> /// <param name="tiles">The number of tiles the image is split into (horizontal and vertically). Minimum value is 2.</param>
public AdaptiveHistEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) public AdaptiveHistEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles)
: base(luminanceLevels, clipHistogram, clipLimitPercentage) : base(luminanceLevels, clipHistogram, clipLimitPercentage)
@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
for (int dx = x; dx < xEnd; dx++) for (int dx = x; dx < xEnd; dx++)
{ {
float luminanceEqualized = this.InterpolateBetweenFourTiles(source[dx, dy], cdfData, tileX, tileY, cdfX, tileYStartPosition.cdfY, tileWidth, tileHeight, pixelsInTile); float luminanceEqualized = this.InterpolateBetweenFourTiles(source[dx, dy], cdfData, tileX, tileY, cdfX, tileYStartPosition.cdfY, tileWidth, tileHeight, pixelsInTile);
pixelRow[dx].FromVector4(new Vector4(luminanceEqualized)); pixelRow[dx].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, pixelRow[dx].ToVector4().W));
tileX++; tileX++;
} }
@ -141,7 +141,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
for (int dx = xStart; dx < xEnd; dx++) for (int dx = xStart; dx < xEnd; dx++)
{ {
float luminanceEqualized = cdfData.RemapGreyValue(this.GetLuminance(source[dx, dy], this.LuminanceLevels), pixelsInTile); float luminanceEqualized = cdfData.RemapGreyValue(this.GetLuminance(source[dx, dy], this.LuminanceLevels), pixelsInTile);
pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized)); pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, source[dx, dy].ToVector4().W));
} }
} }
} }
@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
for (int dx = xStart; dx < xEnd; dx++) for (int dx = xStart; dx < xEnd; dx++)
{ {
float luminanceEqualized = this.InterpolateBetweenTwoTiles(source[dx, dy], cdfData[cdfX, cdfY], cdfData[cdfX, cdfY + 1], tileY, tileHeight, pixelsInTile); float luminanceEqualized = this.InterpolateBetweenTwoTiles(source[dx, dy], cdfData[cdfX, cdfY], cdfData[cdfX, cdfY + 1], tileY, tileHeight, pixelsInTile);
pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized)); pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, source[dx, dy].ToVector4().W));
tileX++; tileX++;
} }
@ -213,7 +213,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
for (int dx = x; dx < xLimit; dx++) for (int dx = x; dx < xLimit; dx++)
{ {
float luminanceEqualized = this.InterpolateBetweenTwoTiles(source[dx, dy], cdfData[cdfX, cdfY], cdfData[cdfX + 1, cdfY], tileX, tileWidth, pixelsInTile); float luminanceEqualized = this.InterpolateBetweenTwoTiles(source[dx, dy], cdfData[cdfX, cdfY], cdfData[cdfX + 1, cdfY], tileX, tileWidth, pixelsInTile);
pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized)); pixels[(dy * source.Width) + dx].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, source[dx, dy].ToVector4().W));
tileX++; tileX++;
} }

9
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationSWProcessor.cs

@ -6,7 +6,6 @@ using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.ParallelUtils;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory; using SixLabors.Memory;
using SixLabors.Primitives; using SixLabors.Primitives;
@ -26,7 +25,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// <param name="luminanceLevels">The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// <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> /// 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="clipHistogram">Indicating whether to clip the histogram bins at a specific value.</param>
/// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the grid. Histogram bins which exceed this limit, will be capped at this value.</param> /// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value.</param>
/// <param name="tiles">The number of tiles the image is split into (horizontal and vertically). Minimum value is 2.</param> /// <param name="tiles">The number of tiles the image is split into (horizontal and vertically). Minimum value is 2.</param>
public AdaptiveHistEqualizationSWProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles) public AdaptiveHistEqualizationSWProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage, int tiles)
: base(luminanceLevels, clipHistogram, clipLimitPercentage) : base(luminanceLevels, clipHistogram, clipLimitPercentage)
@ -71,7 +70,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
Span<TPixel> pixelRow = pixelRowBuffer.GetSpan(); Span<TPixel> pixelRow = pixelRowBuffer.GetSpan();
int maxHistIdx = 0; int maxHistIdx = 0;
// Build the histogram of grayscale values for the current grid. // Build the histogram of grayscale values for the current tile.
for (int dy = -halfTileWith; dy < halfTileWith; dy++) for (int dy = -halfTileWith; dy < halfTileWith; dy++)
{ {
Span<TPixel> rowSpan = this.GetPixelRow(source, pixelRow, (int)x - halfTileWith, dy, tileWidth); Span<TPixel> rowSpan = this.GetPixelRow(source, pixelRow, (int)x - halfTileWith, dy, tileWidth);
@ -91,14 +90,14 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
this.ClipHistogram(histogramCopy, this.ClipLimitPercentage, pixeInTile); this.ClipHistogram(histogramCopy, this.ClipLimitPercentage, pixeInTile);
} }
// Calculate the cumulative distribution function, which will map each input pixel in the current grid to a new value. // Calculate the cumulative distribution function, which will map each input pixel in the current tile to a new value.
int cdfMin = this.ClipHistogramEnabled ? this.CalculateCdf(cdf, histogramCopy, maxHistIdx) : this.CalculateCdf(cdf, histogram, maxHistIdx); int cdfMin = this.ClipHistogramEnabled ? this.CalculateCdf(cdf, histogramCopy, maxHistIdx) : this.CalculateCdf(cdf, histogram, maxHistIdx);
float numberOfPixelsMinusCdfMin = pixeInTile - cdfMin; float numberOfPixelsMinusCdfMin = pixeInTile - cdfMin;
// Map the current pixel to the new equalized value // Map the current pixel to the new equalized value
int luminance = this.GetLuminance(source[x, y], this.LuminanceLevels); int luminance = this.GetLuminance(source[x, y], this.LuminanceLevels);
float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin; float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
targetPixels[x, y].FromVector4(new Vector4(luminanceEqualized)); targetPixels[x, y].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, source[x, y].ToVector4().W));
// Remove top most row from the histogram, mirroring rows which exceeds the borders. // Remove top most row from the histogram, mirroring rows which exceeds the borders.
Span<TPixel> rowSpan = this.GetPixelRow(source, pixelRow, x - halfTileWith, y - halfTileWith, tileWidth); Span<TPixel> rowSpan = this.GetPixelRow(source, pixelRow, x - halfTileWith, y - halfTileWith, tileWidth);

2
src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor.cs

@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels);
float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin; float luminanceEqualized = cdf[luminance] / numberOfPixelsMinusCdfMin;
pixels[i].FromVector4(new Vector4(luminanceEqualized)); pixels[i].FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, sourcePixel.ToVector4().W));
} }
} }
} }

2
src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationOptions.cs

@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// <summary> /// <summary>
/// Gets or sets the histogram clip limit in percent of the total pixels in a tile. Histogram bins which exceed this limit, will be capped at this value. /// Gets or sets the histogram clip limit in percent of the total pixels in a tile. Histogram bins which exceed this limit, will be capped at this value.
/// Defaults to 0.35. /// Defaults to 0.035f.
/// </summary> /// </summary>
public float ClipLimitPercentage { get; set; } = 0.035f; public float ClipLimitPercentage { get; set; } = 0.035f;

8
src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor.cs

@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// <param name="luminanceLevels">The number of different luminance levels. Typical values are 256 for 8-bit grayscale images /// <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> /// or 65536 for 16-bit grayscale images.</param>
/// <param name="clipHistogram">Indicates, if histogram bins should be clipped.</param> /// <param name="clipHistogram">Indicates, if histogram bins should be clipped.</param>
/// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the grid. Histogram bins which exceed this limit, will be capped at this value.</param> /// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value.</param>
protected HistogramEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage) protected HistogramEqualizationProcessor(int luminanceLevels, bool clipHistogram, float clipLimitPercentage)
{ {
Guard.MustBeGreaterThan(luminanceLevels, 0, nameof(luminanceLevels)); Guard.MustBeGreaterThan(luminanceLevels, 0, nameof(luminanceLevels));
@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
public bool ClipHistogramEnabled { get; } public bool ClipHistogramEnabled { get; }
/// <summary> /// <summary>
/// Gets the histogram clip limit in percent of the total pixels in the grid. Histogram bins which exceed this limit, will be capped at this value. /// Gets the histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value.
/// </summary> /// </summary>
public float ClipLimitPercentage { get; } public float ClipLimitPercentage { get; }
@ -79,8 +79,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// the values over the clip limit to all other bins equally. /// the values over the clip limit to all other bins equally.
/// </summary> /// </summary>
/// <param name="histogram">The histogram to apply the clipping.</param> /// <param name="histogram">The histogram to apply the clipping.</param>
/// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the grid. Histogram bins which exceed this limit, will be capped at this value.</param> /// <param name="clipLimitPercentage">Histogram clip limit in percent of the total pixels in the tile. Histogram bins which exceed this limit, will be capped at this value.</param>
/// <param name="pixelCount">The numbers of pixels inside the grid.</param> /// <param name="pixelCount">The numbers of pixels inside the tile.</param>
protected void ClipHistogram(Span<int> histogram, float clipLimitPercentage, int pixelCount) protected void ClipHistogram(Span<int> histogram, float clipLimitPercentage, int pixelCount)
{ {
int clipLimit = Convert.ToInt32(pixelCount * clipLimitPercentage); int clipLimit = Convert.ToInt32(pixelCount * clipLimitPercentage);

Loading…
Cancel
Save