Browse Source

Fix convolution edge detection

Former-commit-id: 7893263bbe8ae48c4c9868d53b4b8d83dacffab4
Former-commit-id: 6eb44d572463eb4d21bf7c5b26ea3836bb4a922e
Former-commit-id: 0c17bfb0eef70231ed7f26bf5b7435ac5a895c88
pull/1/head
James Jackson-South 10 years ago
parent
commit
f1b2d2fce6
  1. 22
      src/ImageProcessorCore/Samplers/DetectEdges.cs
  2. 3
      src/ImageProcessorCore/Samplers/Processors/CompandingResizeProcessor.cs
  3. 19
      src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2DFilter.cs
  4. 2
      src/ImageProcessorCore/Samplers/Processors/Convolution/Convolution2PassFilter.cs
  5. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/ConvolutionFilter.cs
  6. 35
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs
  7. 128
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs
  8. 15
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs
  9. 8
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs
  10. 21
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
  11. 96
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs
  12. 15
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
  13. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
  14. 17
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
  15. 23
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
  16. 21
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
  17. 23
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
  18. 21
      src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs
  19. 2
      src/ImageProcessorCore/Samplers/Processors/Convolution/GuassianBlurProcessor.cs
  20. 2
      src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs
  21. 4
      src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs
  22. 2
      src/ImageProcessorCore/Samplers/Processors/FlipProcessor.cs
  23. 2
      src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs
  24. 2
      src/ImageProcessorCore/Samplers/Processors/OilPaintingProcessor.cs
  25. 2
      src/ImageProcessorCore/Samplers/Processors/PixelateProcessor.cs
  26. 2
      src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs
  27. 2
      src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs
  28. 2
      src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs

22
src/ImageProcessorCore/Samplers/DetectEdges.cs

@ -25,7 +25,7 @@ namespace ImageProcessorCore
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
return DetectEdges(source, source.Bounds, new SobelProcessor<TColor, TPacked> { Grayscale = true }, progressHandler);
return DetectEdges(source, source.Bounds, new SobelProcessor<TColor, TPacked>(true), progressHandler);
}
/// <summary>
@ -44,7 +44,7 @@ namespace ImageProcessorCore
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
return DetectEdges(source, rectangle, new SobelProcessor<TColor, TPacked> { Grayscale = true }, progressHandler);
return DetectEdges(source, rectangle, new SobelProcessor<TColor, TPacked>(true), progressHandler);
}
/// <summary>
@ -86,39 +86,39 @@ namespace ImageProcessorCore
switch (filter)
{
case EdgeDetection.Kayyali:
processor = new KayyaliProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new KayyaliProcessor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.Kirsch:
processor = new KirschProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new KirschProcessor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.Lapacian3X3:
processor = new Laplacian3X3Processor<TColor, TPacked> { Grayscale = grayscale };
processor = new Laplacian3X3Processor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.Lapacian5X5:
processor = new Laplacian5X5Processor<TColor, TPacked> { Grayscale = grayscale };
processor = new Laplacian5X5Processor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.LaplacianOfGaussian:
processor = new LaplacianOfGaussianProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new LaplacianOfGaussianProcessor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.Prewitt:
processor = new PrewittProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new PrewittProcessor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.RobertsCross:
processor = new RobertsCrossProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new RobertsCrossProcessor<TColor, TPacked>(grayscale);
break;
case EdgeDetection.Scharr:
processor = new ScharrProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new ScharrProcessor<TColor, TPacked>(grayscale);
break;
default:
processor = new SobelProcessor<TColor, TPacked> { Grayscale = grayscale };
processor = new SobelProcessor<TColor, TPacked>(grayscale);
break;
}

3
src/ImageProcessorCore/Samplers/Processors/CompandingResizeProcessor.cs

@ -34,7 +34,7 @@ namespace ImageProcessorCore.Processors
public override bool Compand { get; set; } = true;
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
// Jump out, we'll deal with that later.
if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle)
@ -157,7 +157,6 @@ namespace ImageProcessorCore.Processors
this.OnRowProcessed();
});
}
}
}

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

@ -14,22 +14,33 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class Convolution2DFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>
public class Convolution2DFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="Convolution2DFilter{TColor,TPacked}"/> class.
/// </summary>
/// <param name="kernelX">The horizontal gradient operator.</param>
/// <param name="kernelY">The vertical gradient operator.</param>
public Convolution2DFilter(float[,] kernelX, float[,] kernelY)
{
this.KernelX = kernelX;
this.KernelY = kernelY;
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public abstract float[,] KernelX { get; }
public float[,] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public abstract float[,] KernelY { get; }
public float[,] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
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;

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

@ -28,7 +28,7 @@ namespace ImageProcessorCore.Processors
public abstract float[,] KernelY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
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;

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

@ -13,17 +13,26 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class ConvolutionFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>
public class ConvolutionFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <summary>
/// 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)
{
this.KernelXY = kernelXY;
}
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public abstract float[,] KernelXY { get; }
public virtual float[,] KernelXY { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
float[,] kernelX = this.KernelXY;
int kernelLength = kernelX.GetLength(0);
@ -87,8 +96,8 @@ namespace ImageProcessorCore.Processors
TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z));
targetPixels[x, y] = packed;
}
this.OnRowProcessed();
}
});

35
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs

@ -11,12 +11,41 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class EdgeDetector2DFilter<TColor, TPacked> : Convolution2DFilter<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
public class EdgeDetector2DFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="EdgeDetector2DFilter{TColor,TPacked}"/> class.
/// </summary>
/// <param name="kernelX">The horizontal gradient operator.</param>
/// <param name="kernelY">The vertical gradient operator.</param>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public EdgeDetector2DFilter(float[,] kernelX, float[,] kernelY, bool grayscale)
{
this.KernelX = kernelX;
this.KernelY = kernelY;
this.Grayscale = grayscale;
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public float[,] KernelX { get; }
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public float[,] KernelY { get; }
/// <inheritdoc/>
public bool Grayscale { get; set; }
public bool Grayscale { get; }
/// <inheritdoc />
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
new Convolution2DFilter<TColor, TPacked>(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY);
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
@ -27,4 +56,4 @@ namespace ImageProcessorCore.Processors
}
}
}
}
}

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

@ -0,0 +1,128 @@
// <copyright file="EdgeDetectorCompassFilter.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore.Processors
{
using System;
using System.Numerics;
using System.Threading.Tasks;
public class EdgeDetectorCompassFilter<TColor, TPacked> : ImageSampler<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="EdgeDetectorCompassFilter{TColor,TPacked}"/> class.
/// </summary>
/// <param name="kernels">
/// The collection of 2d gradient operator.
/// </param>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public EdgeDetectorCompassFilter(float[][,] kernels, bool grayscale)
{
this.Kernels = kernels;
this.Grayscale = grayscale;
}
/// <summary>
/// Gets the collection of 2d gradient operators.
/// </summary>
public float[][,] Kernels { get; }
/// <inheritdoc />
public bool Grayscale { get; }
/// <inheritdoc />
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
// Align start/end positions.
int minX = Math.Max(0, startX);
int maxX = Math.Min(source.Width, endX);
int minY = Math.Max(0, startY);
int maxY = Math.Min(source.Height, endY);
// Reset offset if necessary.
if (minX > 0)
{
startX = 0;
}
if (minY > 0)
{
startY = 0;
}
new EdgeDetectorFilter<TColor, TPacked>(this.Kernels[0], this.Grayscale).Apply(target, source, sourceRectangle, targetRectangle, startY, endY);
//this.ApplyConvolution(target, source, sourceRectangle, this.Grayscale, this.Kernels[0]);
if (this.Kernels.Length == 1)
{
return;
}
for (int i = 1; i < this.Kernels.Length; i++)
{
ImageBase<TColor, TPacked> pass = new Image<TColor, TPacked>(source.Width, source.Height);
new EdgeDetectorFilter<TColor, TPacked>(this.Kernels[0], false).Apply(pass, source, sourceRectangle, targetRectangle, startY, endY);
// this.ApplyConvolution(pass, source, sourceRectangle, false, this.Kernels[0]);
using (PixelAccessor<TColor, TPacked> passPixels = pass.Lock())
using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{
Parallel.For(
minY,
maxY,
this.ParallelOptions,
y =>
{
int offsetY = y - startY;
for (int x = minX; x < maxX; x++)
{
int offsetX = x - startX;
Vector4 passColor = passPixels[offsetX, offsetY].ToVector4();
Vector4 targetColor = targetPixels[offsetX, offsetY].ToVector4();
TColor packed = default(TColor);
packed.PackFromVector4(Vector4.Max(passColor, targetColor));
targetPixels[offsetX, offsetY] = packed;
}
});
}
}
}
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{
if (this.Grayscale)
{
new GrayscaleBt709Processor<TColor, TPacked>().Apply(source, sourceRectangle);
}
}
/// <summary>
/// Applies the convolution process to the specified portion of the specified <see cref="ImageBase{TColor, TPacked}"/> at the specified location
/// and with the specified size.
/// </summary>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="grayScale">Whether to convert the image to grayscale before performing edge detection.</param>
/// <param name="kernel">The kernel operator.</param>
private void ApplyConvolution(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, bool grayScale, float[,] kernel)
{
new EdgeDetectorFilter<TColor, TPacked>(kernel, grayScale).Apply(target, source, sourceRectangle);
}
}
}

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

@ -11,12 +11,23 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class EdgeDetectorFilter<TColor, TPacked> : ConvolutionFilter<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
public class EdgeDetectorFilter<TColor, TPacked> : ConvolutionFilter<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="EdgeDetectorFilter{TColor,TPacked}"/> class.
/// </summary>
/// <param name="kernelXY">The 2d gradient operator.</param>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public EdgeDetectorFilter(float[,] kernelXY, bool grayscale)
: base(kernelXY)
{
this.Grayscale = grayscale;
}
/// <inheritdoc/>
public bool Grayscale { get; set; }
public bool Grayscale { get; }
/// <inheritdoc/>
protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)

8
src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs

@ -22,9 +22,9 @@ namespace ImageProcessorCore.Processors
public interface IEdgeDetectorFilter
{
/// <summary>
/// Gets or sets a value indicating whether to convert the
/// image to Grayscale before performing edge detection.
/// Gets a value indicating whether to convert the
/// image to grayscale before performing edge detection.
/// </summary>
bool Grayscale { get; set; }
bool Grayscale { get; }
}
}
}

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

@ -15,16 +15,29 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="KayyaliProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public KayyaliProcessor(bool grayscale)
: base(KernelA, KernelB, grayscale)
{
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelA => new float[,]
{
{ 6, 0, -6 },
{ 0, 0, 0 },
{ -6, 0, 6 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public static float[,] KernelB => new float[,]
{
{ -6, 0, 6 },
{ 0, 0, 0 },

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

@ -11,24 +11,100 @@ namespace ImageProcessorCore.Processors
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class KirschProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
public class KirschProcessor<TColor, TPacked> : EdgeDetectorCompassFilter<TColor, TPacked>
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
public KirschProcessor(bool grayscale)
: base(new[] { North, Northwest, West, Southwest, South, Southeast, East, Northeast }, grayscale)
{
{ 5, 5, 5 },
{ -3, 0, -3 },
}
/// <summary>
/// Gets the North direction Kirsch kernel mask.
/// </summary>
///
public static float[,] North => new float[,]
{
{ -3, -3, 5 },
{ -3, 0, 5 },
{ -3, -3, 5 }
};
/// <summary>
/// Gets the Northwest direction Kirsch kernel mask.
/// </summary>
///
public static float[,] Northwest => new float[,]
{
{ -3, 5, 5 },
{ -3, 0, 5 },
{ -3, -3, -3 }
};
/// <summary>
/// Gets the West direction Kirsch kernel mask.
/// </summary>
///
public static float[,] West => new float[,]
{
{ 5, 5, 5 },
{ -3, 0, -3 },
{ -3, -3, -3 }
};
/// <summary>
/// Gets the Southwest direction Kirsch kernel mask.
/// </summary>
///
public static float[,] Southwest => new float[,]
{
{ 5, 5, -3 },
{ 5, 0, -3 },
{ -3, -3, -3 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the South direction Kirsch kernel mask.
/// </summary>
///
public static float[,] South => new float[,]
{
{ 5, -3, -3 },
{ 5, 0, -3 },
{ 5, -3, -3 }
};
/// <summary>
/// Gets the Southeast direction Kirsch kernel mask.
/// </summary>
public static float[,] Southeast => new float[,]
{
{ -3, -3, -3 },
{ 5, 0, -3 },
{ 5, 5, -3 }
};
/// <summary>
/// Gets the East direction Kirsch kernel mask.
/// </summary>
///
public static float[,] East => new float[,]
{
{ -3, -3, -3 },
{ -3, 0, -3 },
{ 5, 5, 5 }
};
/// <summary>
/// Gets the Northeast direction Kirsch kernel mask.
/// </summary>
///
public static float[,] Northeast => new float[,]
{
{ 5, -3, -3 },
{ 5, 0, -3 },
{ 5, -3, -3 }
{ -3, -3, -3 },
{ -3, 0, 5 },
{ -3, 5, 5 }
};
}
}

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

@ -15,8 +15,19 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="Laplacian3X3Processor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public Laplacian3X3Processor(bool grayscale)
: base(Kernel, grayscale)
{
}
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public static float[,] Kernel => new float[,]
{
{ -1, -1, -1 },
{ -1, 8, -1 },

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

@ -15,8 +15,19 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="Laplacian5X5Processor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public Laplacian5X5Processor(bool grayscale)
: base(Kernel, grayscale)
{
}
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public static float[,] Kernel => new float[,]
{
{ -1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1 },
@ -25,4 +36,4 @@ namespace ImageProcessorCore.Processors
{ -1, -1, -1, -1, -1 }
};
}
}
}

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

@ -15,8 +15,19 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelXY => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="LaplacianOfGaussianProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public LaplacianOfGaussianProcessor(bool grayscale)
: base(Kernel, grayscale)
{
}
/// <summary>
/// Gets the 2d gradient operator.
/// </summary>
public static float[,] Kernel => new float[,]
{
{ 0, 0, -1, 0, 0 },
{ 0, -1, -2, -1, 0 },
@ -25,4 +36,4 @@ namespace ImageProcessorCore.Processors
{ 0, 0, -1, 0, 0 }
};
}
}
}

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

@ -15,20 +15,33 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="PrewittProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public PrewittProcessor(bool grayscale)
: base(KernelA, KernelB, grayscale)
{
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelA => new float[,]
{
{ -1, 0, 1 },
{ -1, 0, 1 },
{ -1, 0, 1 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public static float[,] KernelB => new float[,]
{
{ 1, 1, 1 },
{ 0, 0, 0 },
{ -1, -1, -1 }
};
}
}
}

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

@ -15,15 +15,28 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="RobertsCrossProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public RobertsCrossProcessor(bool grayscale)
: base(KernelA, KernelB, grayscale)
{
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelA => new float[,]
{
{ 1, 0 },
{ 0, -1 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public static float[,] KernelB => new float[,]
{
{ 0, 1 },
{ -1, 0 }

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

@ -15,20 +15,33 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="ScharrProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public ScharrProcessor(bool grayscale)
: base(KernelA, KernelB, grayscale)
{
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelA => new float[,]
{
{ -3, 0, 3 },
{ -10, 0, 10 },
{ -3, 0, 3 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the vertical gradient operator.
/// </summary>
public static float[,] KernelB => new float[,]
{
{ 3, 10, 3 },
{ 0, 0, 0 },
{ -3, -10, -3 }
};
}
}
}

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

@ -15,16 +15,29 @@ namespace ImageProcessorCore.Processors
where TColor : IPackedVector<TPacked>
where TPacked : struct
{
/// <inheritdoc/>
public override float[,] KernelX => new float[,]
/// <summary>
/// Initializes a new instance of the <see cref="SobelProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="grayscale">Whether to convert the image to grayscale before performing edge detection..</param>
public SobelProcessor(bool grayscale)
: base(KernelA, KernelB, grayscale)
{
}
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelA => new float[,]
{
{ -1, 0, 1 },
{ -2, 0, 2 },
{ -1, 0, 1 }
};
/// <inheritdoc/>
public override float[,] KernelY => new float[,]
/// <summary>
/// Gets the horizontal gradient operator.
/// </summary>
public static float[,] KernelB => new float[,]
{
{ 1, 2, 1 },
{ 0, 0, 0 },

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

@ -17,7 +17,7 @@ namespace ImageProcessorCore.Processors
where TPacked : struct
{
/// <summary>
/// The maximum size of the kernal in either direction.
/// The maximum size of the kernel in either direction.
/// </summary>
private readonly int kernelSize;

2
src/ImageProcessorCore/Samplers/Processors/CropProcessor.cs

@ -17,7 +17,7 @@ namespace ImageProcessorCore.Processors
where TPacked : struct
{
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int startX = targetRectangle.X;
int endX = targetRectangle.Right;

4
src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs

@ -47,7 +47,7 @@ namespace ImageProcessorCore.Processors
ImageBase<TColor, TPacked> temp = new Image<TColor, TPacked>(source.Width, source.Height);
// Detect the edges.
new SobelProcessor<TColor, TPacked>().Apply(temp, source, sourceRectangle);
new SobelProcessor<TColor, TPacked>(false).Apply(temp, source, sourceRectangle);
// Apply threshold binarization filter.
new BinaryThresholdProcessor<TColor, TPacked>(.5f).Apply(temp, sourceRectangle);
@ -61,7 +61,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
// Jump out, we'll deal with that later.
if (source.Bounds == target.Bounds)

2
src/ImageProcessorCore/Samplers/Processors/FlipProcessor.cs

@ -32,7 +32,7 @@ namespace ImageProcessorCore.Processors
public FlipType FlipType { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
target.ClonePixels(target.Width, target.Height, source.Pixels);

2
src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs

@ -89,7 +89,7 @@ namespace ImageProcessorCore.Processors
/// <remarks>
/// The method keeps the source image unchanged and returns the the result of image process as new image.
/// </remarks>
protected abstract void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY);
public abstract void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY);
/// <summary>
/// This method is called before the process is applied to prepare the processor.

2
src/ImageProcessorCore/Samplers/Processors/OilPaintingProcessor.cs

@ -44,7 +44,7 @@ namespace ImageProcessorCore.Processors
public int BrushSize { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

2
src/ImageProcessorCore/Samplers/Processors/PixelateProcessor.cs

@ -37,7 +37,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; }
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;

2
src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs

@ -33,7 +33,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
// Jump out, we'll deal with that later.
if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle)

2
src/ImageProcessorCore/Samplers/Processors/RotateProcessor.cs

@ -52,7 +52,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
if (OptimizedApply(target, source))
{

2
src/ImageProcessorCore/Samplers/Processors/SkewProcessor.cs

@ -49,7 +49,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
public override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
int height = target.Height;
int width = target.Width;

Loading…
Cancel
Save