Browse Source

Use Jagged array for other edge detection filters.

Former-commit-id: 01b45cf5bc15f50c9e56d9e9ede8459ddda590cc
Former-commit-id: a8dee96f99b651b0513be43d1812c043818a3148
Former-commit-id: 1c4a5a0430cce0695d87fef840d82f637b72e391
af/merge-core
James Jackson-South 9 years ago
parent
commit
41249090d8
  1. 13
      Settings.StyleCop
  2. 20
      src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2DFilter.cs
  3. 12
      src/ImageProcessorCore/Samplers/Processors/Convolution/ConvolutionFilter.cs
  4. 18
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs
  5. 2
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs
  6. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
  7. 124
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs
  8. 18
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
  9. 22
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
  10. 22
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
  11. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
  12. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
  13. 124
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs
  14. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
  15. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs

13
Settings.StyleCop

@ -1,5 +1,5 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<GlobalSettings>
<CollectionProperty Name="RecognizedWords">
<Value>enum</Value>
<Value>exif</Value>
@ -11,14 +11,21 @@
<Value>unzig</Value>
<Value>cb</Value>
<Value>cr</Value>
<Value>Laplacian</Value>
<Value>Sobel</Value>
<Value>Scharr</Value>
<Value>rrggbb</Value>
<Value>rrggbbaa</Value>
</CollectionProperty>
</GlobalSettings>
<Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<AnalyzerSettings>
<StringProperty Name="CompanyName">James Jackson-South</StringProperty>
<StringProperty Name="Copyright">Copyright © James Jackson-South and contributors.
Licensed under the Apache License, Version 2.0.</StringProperty>
<StringProperty Name="Copyright">
Copyright © James Jackson-South and contributors.
Licensed under the Apache License, Version 2.0.
</StringProperty>
</AnalyzerSettings>
</Analyzer>
</Analyzers>

20
src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2DFilter.cs

@ -42,10 +42,10 @@ namespace ImageProcessorCore.Processors
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int kernelYHeight = KernelY.Length;
int kernelYWidth = KernelY[0].Length;
int kernelXHeight = KernelX.Length;
int kernelXWidth = KernelX[0].Length;
int kernelYHeight = this.KernelY.Length;
int kernelYWidth = this.KernelY[0].Length;
int kernelXHeight = this.KernelX.Length;
int kernelXWidth = this.KernelX[0].Length;
int radiusY = kernelYHeight >> 1;
int radiusX = kernelXWidth >> 1;
@ -98,16 +98,16 @@ namespace ImageProcessorCore.Processors
if (fy < kernelXHeight)
{
rX += KernelX[fy][fx] * r;
gX += KernelX[fy][fx] * g;
bX += KernelX[fy][fx] * b;
rX += this.KernelX[fy][fx] * r;
gX += this.KernelX[fy][fx] * g;
bX += this.KernelX[fy][fx] * b;
}
if (fx < kernelYWidth)
{
rY += KernelY[fy][fx] * r;
gY += KernelY[fy][fx] * g;
bY += KernelY[fy][fx] * b;
rY += this.KernelY[fy][fx] * r;
gY += this.KernelY[fy][fx] * g;
bY += this.KernelY[fy][fx] * b;
}
}
}

12
src/ImageProcessorCore/Samplers/Processors/Convolution/ConvolutionFilter.cs

@ -21,7 +21,7 @@ namespace ImageProcessorCore.Processors
/// Initializes a new instance of the <see cref="ConvolutionFilter{TColor,TPacked}"/> class.
/// </summary>
/// <param name="kernelXY">The 2d gradient operator.</param>
public ConvolutionFilter(float[,] kernelXY)
public ConvolutionFilter(float[][] kernelXY)
{
this.KernelXY = kernelXY;
}
@ -29,12 +29,12 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public virtual float[,] KernelXY { get; }
public virtual float[][] KernelXY { 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.KernelXY;
float[][] kernelX = this.KernelXY;
int kernelLength = kernelX.GetLength(0);
int radius = kernelLength >> 1;
@ -82,9 +82,9 @@ namespace ImageProcessorCore.Processors
float g = currentColor.Y;
float b = currentColor.Z;
rX += kernelX[fy, fx] * r;
gX += kernelX[fy, fx] * g;
bX += kernelX[fy, fx] * b;
rX += kernelX[fy][fx] * r;
gX += kernelX[fy][fx] * g;
bX += kernelX[fy][fx] * b;
}
}

18
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs

@ -21,42 +21,42 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the North gradient operator
/// </summary>
public abstract float[,] North { get; }
public abstract float[][] North { get; }
/// <summary>
/// Gets the NorthWest gradient operator
/// </summary>
public abstract float[,] NorthWest { get; }
public abstract float[][] NorthWest { get; }
/// <summary>
/// Gets the West gradient operator
/// </summary>
public abstract float[,] West { get; }
public abstract float[][] West { get; }
/// <summary>
/// Gets the SouthWest gradient operator
/// </summary>
public abstract float[,] SouthWest { get; }
public abstract float[][] SouthWest { get; }
/// <summary>
/// Gets the South gradient operator
/// </summary>
public abstract float[,] South { get; }
public abstract float[][] South { get; }
/// <summary>
/// Gets the SouthEast gradient operator
/// </summary>
public abstract float[,] SouthEast { get; }
public abstract float[][] SouthEast { get; }
/// <summary>
/// Gets the East gradient operator
/// </summary>
public abstract float[,] East { get; }
public abstract float[][] East { get; }
/// <summary>
/// Gets the NorthEast gradient operator
/// </summary>
public abstract float[,] NorthEast { get; }
public abstract float[][] NorthEast { get; }
/// <inheritdoc/>
public bool Grayscale { get; set; }
@ -64,7 +64,7 @@ namespace ImageProcessorCore.Processors
/// <inheritdoc />
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
float[][,] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast };
float[][][] kernels = { this.North, this.NorthWest, this.West, this.SouthWest, this.South, this.SouthEast, this.East, this.NorthEast };
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

2
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs

@ -20,7 +20,7 @@ namespace ImageProcessorCore.Processors
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public abstract float[,] KernelXY { get; }
public abstract float[][] KernelXY { get; }
/// <inheritdoc/>
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)

17
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs

@ -5,24 +5,33 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Kayyali operator filter.
/// <see href="http://edgedetection.webs.com/"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class KayyaliProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
private static readonly float[][] kernelX = new float[3][]
/// <summary>
/// The horizontal gradient operator.
/// </summary>
private static readonly float[][] KayyaliX =
{
new float[] { 6, 0, -6 },
new float[] { 0, 0, 0 },
new float[] { -6, 0, 6 }
};
private static readonly float[][] kernelY = new float[3][]
/// <summary>
/// The vertical gradient operator.
/// </summary>
private static readonly float[][] KayyaliY =
{
new float[] { -6, 0, 6 },
new float[] { 0, 0, 0 },
@ -30,9 +39,9 @@ namespace ImageProcessorCore.Processors
};
/// <inheritdoc/>
public override float[][] KernelX => kernelX;
public override float[][] KernelX => KayyaliX;
/// <inheritdoc/>
public override float[][] KernelY => kernelY;
public override float[][] KernelY => KayyaliY;
}
}

124
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs

@ -2,81 +2,123 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Kirsch operator filter.
/// <see href="http://en.wikipedia.org/wiki/Kirsch_operator"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class KirschProcessor<TColor, TPacked> : EdgeDetectorCompassFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] North => new float[,]
/// <summary>
/// The North gradient operator
/// </summary>
private static readonly float[][] KirschNorth =
{
{ 5, 5, 5 },
{ -3, 0, -3 },
{ -3, -3, -3 }
new float[] { 5, 5, 5 },
new float[] { -3, 0, -3 },
new float[] { -3, -3, -3 }
};
/// <inheritdoc/>
public override float[,] NorthWest => new float[,]
/// <summary>
/// The NorthWest gradient operator
/// </summary>
private static readonly float[][] KirschNorthWest =
{
{ 5, 5, -3 },
{ 5, 0, -3 },
{ -3, -3, -3 }
new float[] { 5, 5, -3 },
new float[] { 5, 0, -3 },
new float[] { -3, -3, -3 }
};
/// <inheritdoc/>
public override float[,] West => new float[,]
/// <summary>
/// The West gradient operator
/// </summary>
private static readonly float[][] KirschWest =
{
{ 5, -3, -3 },
{ 5, 0, -3 },
{ 5, -3, -3 }
new float[] { 5, -3, -3 },
new float[] { 5, 0, -3 },
new float[] { 5, -3, -3 }
};
/// <inheritdoc/>
public override float[,] SouthWest => new float[,]
/// <summary>
/// The SouthWest gradient operator
/// </summary>
private static readonly float[][] KirschSouthWest =
{
{ -3, -3, -3 },
{ 5, 0, -3 },
{ 5, 5, -3 }
new float[] { -3, -3, -3 },
new float[] { 5, 0, -3 },
new float[] { 5, 5, -3 }
};
/// <inheritdoc/>
public override float[,] South => new float[,]
/// <summary>
/// The South gradient operator
/// </summary>
private static readonly float[][] KirschSouth =
{
{ -3, -3, -3 },
{ -3, 0, -3 },
{ 5, 5, 5 }
new float[] { -3, -3, -3 },
new float[] { -3, 0, -3 },
new float[] { 5, 5, 5 }
};
/// <inheritdoc/>
public override float[,] SouthEast => new float[,]
/// <summary>
/// The SouthEast gradient operator
/// </summary>
private static readonly float[][] KirschSouthEast =
{
{ -3, -3, -3 },
{ -3, 0, 5 },
{ -3, 5, 5 }
new float[] { -3, -3, -3 },
new float[] { -3, 0, 5 },
new float[] { -3, 5, 5 }
};
/// <inheritdoc/>
public override float[,] East => new float[,]
/// <summary>
/// The East gradient operator
/// </summary>
private static readonly float[][] KirschEast =
{
{ -3, -3, 5 },
{ -3, 0, 5 },
{ -3, -3, 5 }
new float[] { -3, -3, 5 },
new float[] { -3, 0, 5 },
new float[] { -3, -3, 5 }
};
/// <inheritdoc/>
public override float[,] NorthEast => new float[,]
/// <summary>
/// The NorthEast gradient operator
/// </summary>
private static readonly float[][] KirschNorthEast =
{
{ -3, 5, 5 },
{ -3, 0, 5 },
{ -3, -3, -3 }
new float[] { -3, 5, 5 },
new float[] { -3, 0, 5 },
new float[] { -3, -3, -3 }
};
/// <inheritdoc/>
public override float[][] North => KirschNorth;
/// <inheritdoc/>
public override float[][] NorthWest => KirschNorthWest;
/// <inheritdoc/>
public override float[][] West => KirschWest;
/// <inheritdoc/>
public override float[][] SouthWest => KirschSouthWest;
/// <inheritdoc/>
public override float[][] South => KirschSouth;
/// <inheritdoc/>
public override float[][] SouthEast => KirschSouthEast;
/// <inheritdoc/>
public override float[][] East => KirschEast;
/// <inheritdoc/>
public override float[][] NorthEast => KirschNorthEast;
}
}

18
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs

@ -5,22 +5,30 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Laplacian 3 x 3 operator filter.
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class Laplacian3X3Processor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// The 2d gradient operator.
/// </summary>
private static readonly float[][] Laplacian3X3XY = new float[][]
{
{ -1, -1, -1 },
{ -1, 8, -1 },
{ -1, -1, -1 }
new float[] { -1, -1, -1 },
new float[] { -1, 8, -1 },
new float[] { -1, -1, -1 }
};
/// <inheritdoc/>
public override float[][] KernelXY => Laplacian3X3XY;
}
}

22
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs

@ -5,24 +5,32 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Laplacian 5 x 5 operator filter.
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class Laplacian5X5Processor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// The 2d gradient operator.
/// </summary>
private static readonly float[][] Laplacian5X5XY =
{
{ -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1 },
{ -1, -1, 24, -1, -1 },
{ -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1 }
new float[] { -1, -1, -1, -1, -1 },
new float[] { -1, -1, -1, -1, -1 },
new float[] { -1, -1, 24, -1, -1 },
new float[] { -1, -1, -1, -1, -1 },
new float[] { -1, -1, -1, -1, -1 }
};
/// <inheritdoc/>
public override float[][] KernelXY => Laplacian5X5XY;
}
}

22
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs

@ -5,24 +5,32 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Laplacian of Gaussian operator filter.
/// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class LaplacianOfGaussianProcessor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// The 2d gradient operator.
/// </summary>
private static readonly float[][] LaplacianOfGaussianXY =
{
{ 0, 0, -1, 0, 0 },
{ 0, -1, -2, -1, 0 },
{ -1, -2, 16, -2, -1 },
{ 0, -1, -2, -1, 0 },
{ 0, 0, -1, 0, 0 }
new float[] { 0, 0, -1, 0, 0 },
new float[] { 0, -1, -2, -1, 0 },
new float[] { -1, -2, 16, -2, -1 },
new float[] { 0, -1, -2, -1, 0 },
new float[] { 0, 0, -1, 0, 0 }
};
/// <inheritdoc/>
public override float[][] KernelXY => LaplacianOfGaussianXY;
}
}

17
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs

@ -5,24 +5,33 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Prewitt operator filter.
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class PrewittProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
private static readonly float[][] kernelX = new float[3][]
/// <summary>
/// The horizontal gradient operator.
/// </summary>
private static readonly float[][] PrewittX =
{
new float[] { -1, 0, 1 },
new float[] { -1, 0, 1 },
new float[] { -1, 0, 1 }
};
private static readonly float[][] kernelY = new float[3][]
/// <summary>
/// The vertical gradient operator.
/// </summary>
private static readonly float[][] PrewittY =
{
new float[] { 1, 1, 1 },
new float[] { 0, 0, 0 },
@ -30,9 +39,9 @@ namespace ImageProcessorCore.Processors
};
/// <inheritdoc/>
public override float[][] KernelX => kernelX;
public override float[][] KernelX => PrewittX;
/// <inheritdoc/>
public override float[][] KernelY => kernelY;
public override float[][] KernelY => PrewittY;
}
}

17
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs

@ -5,32 +5,41 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Roberts Cross operator filter.
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class RobertsCrossProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
private static readonly float[][] kernelX = new float[2][]
/// <summary>
/// The horizontal gradient operator.
/// </summary>
private static readonly float[][] RobertsCrossX =
{
new float[] { 1, 0 },
new float[] { 0, -1 }
};
private static readonly float[][] kernelY = new float[2][]
/// <summary>
/// The vertical gradient operator.
/// </summary>
private static readonly float[][] RobertsCrossY =
{
new float[] { 0, 1 },
new float[] { -1, 0 }
};
/// <inheritdoc/>
public override float[][] KernelX => kernelX;
public override float[][] KernelX => RobertsCrossX;
/// <inheritdoc/>
public override float[][] KernelY => kernelY;
public override float[][] KernelY => RobertsCrossY;
}
}

124
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobinsonProcessor.cs

@ -2,81 +2,123 @@
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Kirsch operator filter.
/// <see href="http://www.tutorialspoint.com/dip/Robinson_Compass_Mask.htm"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class RobinsonProcessor<TColor, TPacked> : EdgeDetectorCompassFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] North => new float[,]
/// <summary>
/// The North gradient operator
/// </summary>
private static readonly float[][] RobinsonNorth =
{
{ 1, 2, 1 },
{ 0, 0, 0 },
{ -1, -2, -1 }
new float[] { 1, 2, 1 },
new float[] { 0, 0, 0 },
new float[] { -1, -2, -1 }
};
/// <inheritdoc/>
public override float[,] NorthWest => new float[,]
/// <summary>
/// The NorthWest gradient operator
/// </summary>
private static readonly float[][] RobinsonNorthWest =
{
{ 2, 1, 0 },
{ 1, 0, -1 },
{ 0, -1, -2 }
new float[] { 2, 1, 0 },
new float[] { 1, 0, -1 },
new float[] { 0, -1, -2 }
};
/// <inheritdoc/>
public override float[,] West => new float[,]
/// <summary>
/// The West gradient operator
/// </summary>
private static readonly float[][] RobinsonWest =
{
{ 1, 0, -1 },
{ 2, 0, -2 },
{ 1, 0, -1 }
new float[] { 1, 0, -1 },
new float[] { 2, 0, -2 },
new float[] { 1, 0, -1 }
};
/// <inheritdoc/>
public override float[,] SouthWest => new float[,]
/// <summary>
/// The SouthWest gradient operator
/// </summary>
private static readonly float[][] RobinsonSouthWest =
{
{ 0, -1, -2 },
{ 1, 0, -1 },
{ 2, 1, 0 }
new float[] { 0, -1, -2 },
new float[] { 1, 0, -1 },
new float[] { 2, 1, 0 }
};
/// <inheritdoc/>
public override float[,] South => new float[,]
/// <summary>
/// The South gradient operator
/// </summary>
private static readonly float[][] RobinsonSouth =
{
{ -1, -2, -1 },
{ 0, 0, 0 },
{ 1, 2, 1 }
new float[] { -1, -2, -1 },
new float[] { 0, 0, 0 },
new float[] { 1, 2, 1 }
};
/// <inheritdoc/>
public override float[,] SouthEast => new float[,]
/// <summary>
/// The SouthEast gradient operator
/// </summary>
private static readonly float[][] RobinsonSouthEast =
{
{ -2, -1, 0 },
{ -1, 0, 1 },
{ 0, 1, 2 }
new float[] { -2, -1, 0 },
new float[] { -1, 0, 1 },
new float[] { 0, 1, 2 }
};
/// <inheritdoc/>
public override float[,] East => new float[,]
/// <summary>
/// The East gradient operator
/// </summary>
private static readonly float[][] RobinsonEast =
{
{ -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 }
new float[] { -1, 0, 1 },
new float[] { -2, 0, 2 },
new float[] { -1, 0, 1 }
};
/// <inheritdoc/>
public override float[,] NorthEast => new float[,]
/// <summary>
/// The NorthEast gradient operator
/// </summary>
private static readonly float[][] RobinsonNorthEast =
{
{ 0, 1, 2 },
{ -1, 0, 1 },
{ -2, -1, 0 }
new float[] { 0, 1, 2 },
new float[] { -1, 0, 1 },
new float[] { -2, -1, 0 }
};
/// <inheritdoc/>
public override float[][] North => RobinsonNorth;
/// <inheritdoc/>
public override float[][] NorthWest => RobinsonNorthWest;
/// <inheritdoc/>
public override float[][] West => RobinsonWest;
/// <inheritdoc/>
public override float[][] SouthWest => RobinsonSouthWest;
/// <inheritdoc/>
public override float[][] South => RobinsonSouth;
/// <inheritdoc/>
public override float[][] SouthEast => RobinsonSouthEast;
/// <inheritdoc/>
public override float[][] East => RobinsonEast;
/// <inheritdoc/>
public override float[][] NorthEast => RobinsonNorthEast;
}
}

17
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs

@ -5,24 +5,33 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Scharr operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class ScharrProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
private static readonly float[][] kernelX = new float[3][]
/// <summary>
/// The horizontal gradient operator.
/// </summary>
private static readonly float[][] ScharrX = new float[3][]
{
new float[] { -3, 0, 3 },
new float[] { -10, 0, 10 },
new float[] { -3, 0, 3 }
};
private static readonly float[][] kernelY = new float[3][]
/// <summary>
/// The vertical gradient operator.
/// </summary>
private static readonly float[][] ScharrY = new float[3][]
{
new float[] { 3, 10, 3 },
new float[] { 0, 0, 0 },
@ -30,9 +39,9 @@ namespace ImageProcessorCore.Processors
};
/// <inheritdoc/>
public override float[][] KernelX => kernelX;
public override float[][] KernelX => ScharrX;
/// <inheritdoc/>
public override float[][] KernelY => kernelY;
public override float[][] KernelY => ScharrY;
}
}

17
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs

@ -5,24 +5,33 @@
namespace ImageProcessorCore.Processors
{
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// The Sobel operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/>
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
[SuppressMessage("ReSharper", "StaticMemberInGenericType", Justification = "We want to use only one instance of each array field for each generic type.")]
public class SobelProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
private static readonly float[][] kernelX = new float[3][]
/// <summary>
/// The horizontal gradient operator.
/// </summary>
private static readonly float[][] SobelX =
{
new float[] { -1, 0, 1 },
new float[] { -2, 0, 2 },
new float[] { -1, 0, 1 }
};
private static readonly float[][] kernelY = new float[3][]
/// <summary>
/// The vertical gradient operator.
/// </summary>
private static readonly float[][] SobelY =
{
new float[] { -1, -2, -1 },
new float[] { 0, 0, 0 },
@ -30,9 +39,9 @@ namespace ImageProcessorCore.Processors
};
/// <inheritdoc/>
public override float[][] KernelX => kernelX;
public override float[][] KernelX => SobelX;
/// <inheritdoc/>
public override float[][] KernelY => kernelY;
public override float[][] KernelY => SobelY;
}
}

Loading…
Cancel
Save