From 80660c935b9d4d64393b3697f557d9f3387761af Mon Sep 17 00:00:00 2001 From: popow Date: Wed, 5 Dec 2018 20:42:26 +0100 Subject: [PATCH] fixing corner tiles --- .../AdaptiveHistEqualizationProcessor.cs | 51 ++++++++++++++++--- 1 file changed, 43 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs index d055e8b862..767feb0600 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistEqualizationProcessor.cs @@ -104,6 +104,41 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization // fix bottom row this.ProcessBorderRow(source, pixels, cdfData, this.Tiles - 1, tileWidth, tileHeight, yStart: source.Height - halfTileHeight, yEnd: source.Height); + + // left top corner + this.ProcessCornerTile(source, pixels, cdfData[0, 0], xStart: 0, xEnd: halfTileWidth, yStart: 0, yEnd: halfTileHeight, pixelsInTile: pixelsInTile); + + // left bottom corner + this.ProcessCornerTile(source, pixels, cdfData[0, this.Tiles - 1], xStart: 0, xEnd: halfTileWidth, yStart: source.Height - halfTileHeight, yEnd: source.Height, pixelsInTile: pixelsInTile); + + // right top corner + this.ProcessCornerTile(source, pixels, cdfData[this.Tiles - 1, 0], xStart: source.Width - halfTileWidth, xEnd: source.Width, yStart: 0, yEnd: halfTileHeight, pixelsInTile: pixelsInTile); + + // right bottom corner + this.ProcessCornerTile(source, pixels, cdfData[this.Tiles - 1, this.Tiles - 1], xStart: source.Width - halfTileWidth, xEnd: source.Width, yStart: source.Height - halfTileHeight, yEnd: source.Height, pixelsInTile: pixelsInTile); + } + } + + /// + /// Processes the part of a corner tile which was previously left out. It consists of 1 / 4 of a tile and does not need interpolation. + /// + /// The source image. + /// The output pixels. + /// The lookup table to remap the grey values. + /// X start position. + /// X end position. + /// Y start position. + /// Y end position. + /// Pixels in a tile. + private void ProcessCornerTile(ImageFrame source, Span pixels, CdfData cdfData, int xStart, int xEnd, int yStart, int yEnd, int pixelsInTile) + { + for (int dy = yStart; dy < yEnd; dy++) + { + for (int dx = xStart; dx < xEnd; dx++) + { + float luminanceEqualized = cdfData.RemapGreyValue(this.GetLuminance(source[dx, dy], this.LuminanceLevels), pixelsInTile); + pixels[(dy * source.Width) + dx].PackFromVector4(new Vector4(luminanceEqualized)); + } } } @@ -200,7 +235,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// A re-mapped grey value. private float InterpolateBetweenFourTiles(TPixel sourcePixel, CdfData[,] cdfData, int tileX, int tileY, int cdfX, int cdfY, int tileWidth, int tileHeight, int pixelsInTile) { - int luminace = this.GetLuminance(sourcePixel, this.LuminanceLevels); + int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); float tx = tileX / (float)(tileWidth - 1); float ty = tileY / (float)(tileHeight - 1); @@ -209,10 +244,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization int xLeft = cdfX; int xRight = Math.Min(this.Tiles - 1, xLeft + 1); - float cdfLeftTopLuminance = cdfData[xLeft, yTop].RemapGreyValue(luminace, pixelsInTile); - float cdfRightTopLuminance = cdfData[xRight, yTop].RemapGreyValue(luminace, pixelsInTile); - float cdfLeftBottomLuminance = cdfData[xLeft, yBottom].RemapGreyValue(luminace, pixelsInTile); - float cdfRightBottomLuminance = cdfData[xRight, yBottom].RemapGreyValue(luminace, pixelsInTile); + float cdfLeftTopLuminance = cdfData[xLeft, yTop].RemapGreyValue(luminance, pixelsInTile); + float cdfRightTopLuminance = cdfData[xRight, yTop].RemapGreyValue(luminance, pixelsInTile); + float cdfLeftBottomLuminance = cdfData[xLeft, yBottom].RemapGreyValue(luminance, pixelsInTile); + float cdfRightBottomLuminance = cdfData[xRight, yBottom].RemapGreyValue(luminance, pixelsInTile); float luminanceEqualized = this.BilinearInterpolation(tx, ty, cdfLeftTopLuminance, cdfRightTopLuminance, cdfLeftBottomLuminance, cdfRightBottomLuminance); return luminanceEqualized; @@ -230,11 +265,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization /// A re-mapped grey value. private float InterpolateBetweenTwoTiles(TPixel sourcePixel, CdfData cdfData1, CdfData cdfData2, int tilePos, int tileWidth, int pixelsInTile) { - int luminace = this.GetLuminance(sourcePixel, this.LuminanceLevels); + int luminance = this.GetLuminance(sourcePixel, this.LuminanceLevels); float tx = tilePos / (float)(tileWidth - 1); - float cdfLuminance1 = cdfData1.RemapGreyValue(luminace, pixelsInTile); - float cdfLuminance2 = cdfData2.RemapGreyValue(luminace, pixelsInTile); + float cdfLuminance1 = cdfData1.RemapGreyValue(luminance, pixelsInTile); + float cdfLuminance2 = cdfData2.RemapGreyValue(luminance, pixelsInTile); float luminanceEqualized = this.LinearInterpolation(cdfLuminance1, cdfLuminance2, tx); return luminanceEqualized;