Browse Source

Use Jagged array for blur/sharpen.

Former-commit-id: 5f81ab7f9ce979eebccb5655ee29e105b7303806
Former-commit-id: 7de02600717df05b1dce161be06591f00d58f0e0
Former-commit-id: 60489cc8b8d44251df7357da80d30d6ea1a922fc
af/merge-core
James Jackson-South 9 years ago
parent
commit
9903945b53
  1. 24
      src/ImageProcessorCore/Samplers/Processors/Convolution/BoxBlurProcessor.cs
  2. 18
      src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2PassFilter.cs
  3. 24
      src/ImageProcessorCore/Samplers/Processors/Convolution/GuassianBlurProcessor.cs
  4. 32
      src/ImageProcessorCore/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs

24
src/ImageProcessorCore/Samplers/Processors/Convolution/BoxBlurProcessor.cs

@ -35,12 +35,12 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public float[,] KernelX { get; }
public float[][] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public float[,] KernelY { get; }
public float[][] KernelY { get; }
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
@ -52,11 +52,17 @@ namespace ImageProcessorCore.Processors
/// Create a 1 dimensional Box kernel.
/// </summary>
/// <param name="horizontal">Whether to calculate a horizontal kernel.</param>
/// <returns>The <see cref="T:float[,]"/></returns>
private float[,] CreateBoxKernel(bool horizontal)
/// <returns>The <see cref="T:float[][]"/></returns>
private float[][] CreateBoxKernel(bool horizontal)
{
int size = this.kernelSize;
float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
float[][] kernel = horizontal ? new float[1][] : new float[size][];
if (horizontal)
{
kernel[0] = new float[size];
}
float sum = 0.0f;
for (int i = 0; i < size; i++)
@ -65,11 +71,11 @@ namespace ImageProcessorCore.Processors
sum += x;
if (horizontal)
{
kernel[0, i] = x;
kernel[0][i] = x;
}
else
{
kernel[i, 0] = x;
kernel[i] = new[] { x };
}
}
@ -78,14 +84,14 @@ namespace ImageProcessorCore.Processors
{
for (int i = 0; i < size; i++)
{
kernel[0, i] = kernel[0, i] / sum;
kernel[0][i] = kernel[0][i] / sum;
}
}
else
{
for (int i = 0; i < size; i++)
{
kernel[i, 0] = kernel[i, 0] / sum;
kernel[i][0] = kernel[i][0] / sum;
}
}

18
src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2PassFilter.cs

@ -22,7 +22,7 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <param name="kernelX">The horizontal gradient operator.</param>
/// <param name="kernelY">The vertical gradient operator.</param>
public Convolution2PassFilter(float[,] kernelX, float[,] kernelY)
public Convolution2PassFilter(float[][] kernelX, float[][] kernelY)
{
this.KernelX = kernelX;
this.KernelY = kernelY;
@ -31,18 +31,18 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public float[,] KernelX { get; }
public float[][] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public float[,] KernelY { get; }
public float[][] KernelY { get; }
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
float[,] kernelX = this.KernelX;
float[,] kernelY = this.KernelY;
float[][] kernelX = this.KernelX;
float[][] kernelY = this.KernelY;
ImageBase<TColor, TPacked> firstPass = new Image<TColor, TPacked>(source.Width, source.Height);
this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX);
@ -61,10 +61,10 @@ namespace ImageProcessorCore.Processors
/// <param name="startY">The index of the row within the source image to start processing.</param>
/// <param name="endY">The index of the row within the source image to end processing.</param>
/// <param name="kernel">The kernel operator.</param>
private void ApplyConvolution(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY, float[,] kernel)
private void ApplyConvolution(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY, float[][] kernel)
{
int kernelHeight = kernel.GetLength(0);
int kernelWidth = kernel.GetLength(1);
int kernelHeight = kernel.Length;
int kernelWidth = kernel[0].Length;
int radiusY = kernelHeight >> 1;
int radiusX = kernelWidth >> 1;
@ -103,7 +103,7 @@ namespace ImageProcessorCore.Processors
offsetX = offsetX.Clamp(0, maxX);
Vector4 currentColor = sourcePixels[offsetX, offsetY].ToVector4();
destination += kernel[fy, fx] * currentColor;
destination += kernel[fy][fx] * currentColor;
}
}

24
src/ImageProcessorCore/Samplers/Processors/Convolution/GuassianBlurProcessor.cs

@ -73,12 +73,12 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public float[,] KernelX { get; }
public float[][] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public float[,] KernelY { get; }
public float[][] KernelY { get; }
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
@ -90,12 +90,18 @@ namespace ImageProcessorCore.Processors
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
/// </summary>
/// <param name="horizontal">Whether to calculate a horizontal kernel.</param>
/// <returns>The <see cref="T:float[,]"/></returns>
private float[,] CreateGaussianKernel(bool horizontal)
/// <returns>The <see cref="T:float[][]"/></returns>
private float[][] CreateGaussianKernel(bool horizontal)
{
int size = this.kernelSize;
float weight = this.sigma;
float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
float[][] kernel = horizontal ? new float[1][] : new float[size][];
if (horizontal)
{
kernel[0] = new float[size];
}
float sum = 0.0f;
float midpoint = (size - 1) / 2f;
@ -106,11 +112,11 @@ namespace ImageProcessorCore.Processors
sum += gx;
if (horizontal)
{
kernel[0, i] = gx;
kernel[0][i] = gx;
}
else
{
kernel[i, 0] = gx;
kernel[i] = new[] { gx };
}
}
@ -119,14 +125,14 @@ namespace ImageProcessorCore.Processors
{
for (int i = 0; i < size; i++)
{
kernel[0, i] = kernel[0, i] / sum;
kernel[0][i] = kernel[0][i] / sum;
}
}
else
{
for (int i = 0; i < size; i++)
{
kernel[i, 0] = kernel[i, 0] / sum;
kernel[i][0] = kernel[i][0] / sum;
}
}

32
src/ImageProcessorCore/Samplers/Processors/Convolution/GuassianSharpenProcessor.cs

@ -75,12 +75,12 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public float[,] KernelX { get; }
public float[][] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public float[,] KernelY { get; }
public float[][] KernelY { get; }
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
@ -92,12 +92,18 @@ namespace ImageProcessorCore.Processors
/// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
/// </summary>
/// <param name="horizontal">Whether to calculate a horizontal kernel.</param>
/// <returns>The <see cref="T:float[,]"/></returns>
private float[,] CreateGaussianKernel(bool horizontal)
/// <returns>The <see cref="T:float[][]"/></returns>
private float[][] CreateGaussianKernel(bool horizontal)
{
int size = this.kernelSize;
float weight = this.sigma;
float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
float[][] kernel = horizontal ? new float[1][] : new float[size][];
if (horizontal)
{
kernel[0] = new float[size];
}
float sum = 0;
float midpoint = (size - 1) / 2f;
@ -108,11 +114,11 @@ namespace ImageProcessorCore.Processors
sum += gx;
if (horizontal)
{
kernel[0, i] = gx;
kernel[0][i] = gx;
}
else
{
kernel[i, 0] = gx;
kernel[i] = new[] { gx };
}
}
@ -126,12 +132,12 @@ namespace ImageProcessorCore.Processors
if (i == midpointRounded)
{
// Calculate central value
kernel[0, i] = (2f * sum) - kernel[0, i];
kernel[0][i] = (2f * sum) - kernel[0][i];
}
else
{
// invert value
kernel[0, i] = -kernel[0, i];
kernel[0][i] = -kernel[0][i];
}
}
}
@ -142,12 +148,12 @@ namespace ImageProcessorCore.Processors
if (i == midpointRounded)
{
// Calculate central value
kernel[i, 0] = (2 * sum) - kernel[i, 0];
kernel[i][0] = (2 * sum) - kernel[i][0];
}
else
{
// invert value
kernel[i, 0] = -kernel[i, 0];
kernel[i][0] = -kernel[i][0];
}
}
}
@ -157,14 +163,14 @@ namespace ImageProcessorCore.Processors
{
for (int i = 0; i < size; i++)
{
kernel[0, i] = kernel[0, i] / sum;
kernel[0][i] = kernel[0][i] / sum;
}
}
else
{
for (int i = 0; i < size; i++)
{
kernel[i, 0] = kernel[i, 0] / sum;
kernel[i][0] = kernel[i][0] / sum;
}
}

Loading…
Cancel
Save