Browse Source

simplified interpolation between the tiles

pull/673/head
popow 8 years ago
parent
commit
176e7e9f83
  1. 53
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs

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

@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
Span<int> histogram = histogramBuffer.GetSpan();
Span<int> cdf = cdfBuffer.GetSpan();
// The image is split up in square tiles of the size of the parameter GridSize.
// The image is split up into square tiles of the size of the parameter GridSize.
// For each tile the cumulative distribution function will be calculated.
int cdfPosX = 0;
int cdfPosY = 0;
@ -97,10 +97,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
int tilePosX = 0;
int tilePosY = 0;
for (int y = halfGridSize; y < source.Height - halfGridSize; y += this.GridSize)
for (int y = halfGridSize; y < source.Height - this.GridSize; y += this.GridSize)
{
tilePosX = 0;
for (int x = halfGridSize; x < source.Width - halfGridSize; x += this.GridSize)
for (int x = halfGridSize; x < source.Width - this.GridSize; x += this.GridSize)
{
int gridPosX = 0;
int gridPosY = 0;
@ -109,17 +109,24 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
for (int dy = y; dy < ylimit; dy++)
{
gridPosX = 0;
float ty = gridPosY / (float)(this.GridSize - 1);
int yTop = tilePosY;
int yBottom = yTop + 1;
for (int dx = x; dx < xlimit; dx++)
{
TPixel sourcePixel = source[dx, dy];
int luminace = this.GetLuminance(sourcePixel, this.LuminanceLevels);
float cdfLeftTopLuminance = cdfData[tilePosX, tilePosY].RemapGreyValue(luminace, pixelsInGrid);
float cdfRightTopLuminance = cdfData[tilePosX + 1, tilePosY].RemapGreyValue(luminace, pixelsInGrid);
float cdfLeftBottomLuminance = cdfData[tilePosX, tilePosY + 1].RemapGreyValue(luminace, pixelsInGrid);
float cdfRightBottomLuminance = cdfData[tilePosX + 1, tilePosY + 1].RemapGreyValue(luminace, pixelsInGrid);
int xLeft = tilePosX;
int xRight = tilePosX + 1;
float cdfLeftTopLuminance = cdfData[xLeft, yTop].RemapGreyValue(luminace, pixelsInGrid);
float cdfRightTopLuminance = cdfData[xRight, yTop].RemapGreyValue(luminace, pixelsInGrid);
float cdfLeftBottomLuminance = cdfData[xLeft, yBottom].RemapGreyValue(luminace, pixelsInGrid);
float cdfRightBottomLuminance = cdfData[xRight, yBottom].RemapGreyValue(luminace, pixelsInGrid);
float luminanceEqualized = this.BilinearInterpolation(gridPosX, gridPosY, gridPosX / (float)(this.GridSize - 1), ty, cdfLeftTopLuminance, cdfRightTopLuminance, cdfLeftBottomLuminance, cdfRightBottomLuminance);
float luminanceEqualized = this.BilinearInterpolation(gridPosX, gridPosY, this.GridSize, cdfLeftTopLuminance, cdfRightTopLuminance, cdfLeftBottomLuminance, cdfRightBottomLuminance);
pixels[(dy * source.Width) + dx].PackFromVector4(new Vector4(luminanceEqualized));
gridPosX++;
}
@ -140,20 +147,28 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
/// </summary>
/// <param name="x">X position.</param>
/// <param name="y">Y position.</param>
/// <param name="gridSize">The size of the grid.</param>
/// <param name="lt">Luminance from tile top left.</param>
/// <param name="rt">Luminance from tile right top.</param>
/// <param name="lb">Luminance from tile left bottom.</param>
/// <param name="rb">Luminance from tile right bottom.</param>
/// <param name="tx">The interpolation value in x direction in the range of [0, 1].</param>
/// <param name="ty">The interpolation value in y direction in the range of [0, 1].</param>
/// <param name="lt">Luminance from top left tile.</param>
/// <param name="rt">Luminance from right top tile.</param>
/// <param name="lb">Luminance from left bottom tile.</param>
/// <param name="rb">Luminance from right bottom tile.</param>
/// <returns>Interpolated Luminance.</returns>
private float BilinearInterpolation(int x, int y, int gridSize, float lt, float rt, float lb, float rb)
private float BilinearInterpolation(int x, int y, float tx, float ty, float lt, float rt, float lb, float rb)
{
float r1 = ((gridSize - x) / (float)gridSize * lb) + ((x / (float)gridSize) * rb);
float r2 = ((gridSize - x) / (float)gridSize * lt) + ((x / (float)gridSize) * rt);
float res = ((y / ((float)gridSize)) * r1) + (((y - gridSize) / (float)(-gridSize)) * r2);
return this.LinearInterpolation(this.LinearInterpolation(lt, rt, tx), this.LinearInterpolation(lb, rb, tx), ty);
}
return res;
/// <summary>
/// Linear interpolation between two grey values.
/// </summary>
/// <param name="left">The left value.</param>
/// <param name="right">The right value.</param>
/// <param name="t">The interpolation value between the two values in the range of [0, 1].</param>
/// <returns>The interpolated value.</returns>
private float LinearInterpolation(float left, float right, float t)
{
return left + ((right - left) * t);
}
private class CdfData

Loading…
Cancel
Save