diff --git a/src/ImageSharp/Processing/Extensions/Convolution/DetectEdgesExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/DetectEdgesExtensions.cs
index f30d8ad57..2377151bb 100644
--- a/src/ImageSharp/Processing/Extensions/Convolution/DetectEdgesExtensions.cs
+++ b/src/ImageSharp/Processing/Extensions/Convolution/DetectEdgesExtensions.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
-using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.ImageSharp.Processing.Processors.Convolution;
namespace SixLabors.ImageSharp.Processing
@@ -12,144 +11,230 @@ namespace SixLabors.ImageSharp.Processing
public static class DetectEdgesExtensions
{
///
- /// Detects any edges within the image. Uses the filter
- /// operating in grayscale mode.
+ /// Detects any edges within the image.
+ /// Uses the kernel operating in grayscale mode.
///
/// The image this method extends.
/// The to allow chaining of operations.
public static IImageProcessingContext DetectEdges(this IImageProcessingContext source) =>
- DetectEdges(source, new SobelProcessor(true));
+ DetectEdges(source, KnownEdgeDetectorKernels.Sobel);
///
- /// Detects any edges within the image. Uses the filter
- /// operating in grayscale mode.
+ /// Detects any edges within the image.
+ /// Uses the kernel operating in grayscale mode.
///
/// The image this method extends.
///
/// The structure that specifies the portion of the image object to alter.
///
/// The to allow chaining of operations.
- public static IImageProcessingContext DetectEdges(this IImageProcessingContext source, Rectangle rectangle) =>
- DetectEdges(source, rectangle, new SobelProcessor(true));
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ Rectangle rectangle) =>
+ DetectEdges(source, KnownEdgeDetectorKernels.Sobel, rectangle);
///
- /// Detects any edges within the image.
+ /// Detects any edges within the image operating in grayscale mode.
///
/// The image this method extends.
- /// The filter for detecting edges.
+ /// The 2D edge detector kernel.
/// The to allow chaining of operations.
public static IImageProcessingContext DetectEdges(
this IImageProcessingContext source,
- KnownEdgeDetectionOperators filter) =>
- DetectEdges(source, GetProcessor(filter, true));
+ EdgeDetector2DKernel kernel) =>
+ DetectEdges(source, kernel, true);
///
- /// Detects any edges within the image.
+ /// Detects any edges within the image using a .
///
/// The image this method extends.
- /// The filter for detecting edges.
- /// Whether to convert the image to grayscale first. Defaults to true.
+ /// The 2D edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
+ ///
/// The to allow chaining of operations.
public static IImageProcessingContext DetectEdges(
this IImageProcessingContext source,
- KnownEdgeDetectionOperators filter,
- bool grayscale) =>
- DetectEdges(source, GetProcessor(filter, grayscale));
+ EdgeDetector2DKernel kernel,
+ bool grayscale)
+ {
+ var processor = new EdgeDetector2DProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor);
+ return source;
+ }
///
- /// Detects any edges within the image.
+ /// Detects any edges within the image operating in grayscale mode.
///
/// The image this method extends.
- /// The filter for detecting edges.
+ /// The 2D edge detector kernel.
///
/// The structure that specifies the portion of the image object to alter.
///
- /// Whether to convert the image to grayscale first. Defaults to true.
/// The to allow chaining of operations.
public static IImageProcessingContext DetectEdges(
this IImageProcessingContext source,
- KnownEdgeDetectionOperators filter,
- Rectangle rectangle,
- bool grayscale = true) =>
- DetectEdges(source, rectangle, GetProcessor(filter, grayscale));
+ EdgeDetector2DKernel kernel,
+ Rectangle rectangle) =>
+ DetectEdges(source, kernel, true, rectangle);
///
- /// Detects any edges within the image.
+ /// Detects any edges within the image using a .
///
/// The image this method extends.
- /// The filter for detecting edges.
+ /// The 2D edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
+ ///
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
/// The to allow chaining of operations.
- private static IImageProcessingContext DetectEdges(this IImageProcessingContext source, IImageProcessor filter)
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetector2DKernel kernel,
+ bool grayscale,
+ Rectangle rectangle)
{
- return source.ApplyProcessor(filter);
+ var processor = new EdgeDetector2DProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor, rectangle);
+ return source;
}
///
- /// Detects any edges within the image.
+ /// Detects any edges within the image operating in grayscale mode.
///
/// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
+ /// The edge detector kernel.
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorKernel kernel) =>
+ DetectEdges(source, kernel, true);
+
+ ///
+ /// Detects any edges within the image using a .
+ ///
+ /// The image this method extends.
+ /// The edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
///
- /// The filter for detecting edges.
/// The to allow chaining of operations.
- private static IImageProcessingContext DetectEdges(
+ public static IImageProcessingContext DetectEdges(
this IImageProcessingContext source,
- Rectangle rectangle,
- IImageProcessor filter)
+ EdgeDetectorKernel kernel,
+ bool grayscale)
{
- source.ApplyProcessor(filter, rectangle);
+ var processor = new EdgeDetectorProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor);
return source;
}
- private static IImageProcessor GetProcessor(KnownEdgeDetectionOperators filter, bool grayscale)
- {
- IImageProcessor processor;
-
- switch (filter)
- {
- case KnownEdgeDetectionOperators.Kayyali:
- processor = new KayyaliProcessor(grayscale);
- break;
-
- case KnownEdgeDetectionOperators.Kirsch:
- processor = new KirschProcessor(grayscale);
- break;
-
- case KnownEdgeDetectionOperators.Laplacian3x3:
- processor = new Laplacian3x3Processor(grayscale);
- break;
-
- case KnownEdgeDetectionOperators.Laplacian5x5:
- processor = new Laplacian5x5Processor(grayscale);
- break;
-
- case KnownEdgeDetectionOperators.LaplacianOfGaussian:
- processor = new LaplacianOfGaussianProcessor(grayscale);
- break;
-
- case KnownEdgeDetectionOperators.Prewitt:
- processor = new PrewittProcessor(grayscale);
- break;
+ ///
+ /// Detects any edges within the image operating in grayscale mode.
+ ///
+ /// The image this method extends.
+ /// The edge detector kernel.
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorKernel kernel,
+ Rectangle rectangle) =>
+ DetectEdges(source, kernel, true, rectangle);
- case KnownEdgeDetectionOperators.RobertsCross:
- processor = new RobertsCrossProcessor(grayscale);
- break;
+ ///
+ /// Detects any edges within the image using a .
+ ///
+ /// The image this method extends.
+ /// The edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
+ ///
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorKernel kernel,
+ bool grayscale,
+ Rectangle rectangle)
+ {
+ var processor = new EdgeDetectorProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor, rectangle);
+ return source;
+ }
- case KnownEdgeDetectionOperators.Robinson:
- processor = new RobinsonProcessor(grayscale);
- break;
+ ///
+ /// Detects any edges within the image operating in grayscale mode.
+ ///
+ /// The image this method extends.
+ /// Thecompass edge detector kernel.
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorCompassKernel kernel) =>
+ DetectEdges(source, kernel, true);
- case KnownEdgeDetectionOperators.Scharr:
- processor = new ScharrProcessor(grayscale);
- break;
+ ///
+ /// Detects any edges within the image using a .
+ ///
+ /// The image this method extends.
+ /// Thecompass edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorCompassKernel kernel,
+ bool grayscale)
+ {
+ var processor = new EdgeDetectorCompassProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor);
+ return source;
+ }
- default:
- processor = new SobelProcessor(grayscale);
- break;
- }
+ ///
+ /// Detects any edges within the image operating in grayscale mode.
+ ///
+ /// The image this method extends.
+ /// Thecompass edge detector kernel.
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorCompassKernel kernel,
+ Rectangle rectangle) =>
+ DetectEdges(source, kernel, true, rectangle);
- return processor;
+ ///
+ /// Detects any edges within the image using a .
+ ///
+ /// The image this method extends.
+ /// Thecompass edge detector kernel.
+ ///
+ /// Whether to convert the image to grayscale before performing edge detection.
+ ///
+ ///
+ /// The structure that specifies the portion of the image object to alter.
+ ///
+ /// The to allow chaining of operations.
+ public static IImageProcessingContext DetectEdges(
+ this IImageProcessingContext source,
+ EdgeDetectorCompassKernel kernel,
+ bool grayscale,
+ Rectangle rectangle)
+ {
+ var processor = new EdgeDetectorCompassProcessor(kernel, grayscale);
+ source.ApplyProcessor(processor, rectangle);
+ return source;
}
}
}
diff --git a/src/ImageSharp/Processing/KnownEdgeDetectionOperators.cs b/src/ImageSharp/Processing/KnownEdgeDetectorKernels.cs
similarity index 97%
rename from src/ImageSharp/Processing/KnownEdgeDetectionOperators.cs
rename to src/ImageSharp/Processing/KnownEdgeDetectorKernels.cs
index e41fb00ce..2e279d340 100644
--- a/src/ImageSharp/Processing/KnownEdgeDetectionOperators.cs
+++ b/src/ImageSharp/Processing/KnownEdgeDetectorKernels.cs
@@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Processing
///
/// Contains reusable static instances of known edge detection kernels.
///
- public static class KnownEdgeDetectionOperators
+ public static class KnownEdgeDetectorKernels
{
///
/// Gets the Kayyali edge detector kernel.
diff --git a/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
index ebc8f0e4f..dd9c06938 100644
--- a/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
+++ b/src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
@@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
Configuration configuration = this.Source.GetConfiguration();
// Detect the edges.
- new SobelProcessor(false).Execute(this.Configuration, temp, this.SourceRectangle);
+ new EdgeDetector2DProcessor(KnownEdgeDetectorKernels.Sobel, false).Execute(this.Configuration, temp, this.SourceRectangle);
// Apply threshold binarization filter.
new BinaryThresholdProcessor(this.definition.Threshold).Execute(this.Configuration, temp, this.SourceRectangle);
diff --git a/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs b/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
index cf46c4f52..ce2fa988c 100644
--- a/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
+++ b/tests/ImageSharp.Benchmarks/Samplers/DetectEdges.cs
@@ -37,17 +37,17 @@ namespace SixLabors.ImageSharp.Benchmarks
[Benchmark(Description = "ImageSharp DetectEdges")]
public void ImageProcessorCoreDetectEdges()
{
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Kayyali));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Kayyali));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Kirsch));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Laplacian3x3));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Laplacian5x5));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.LaplacianOfGaussian));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Prewitt));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.RobertsCross));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Robinson));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Scharr));
- this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectionOperators.Sobel));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Kayyali));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Kayyali));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Kirsch));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Laplacian3x3));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Laplacian5x5));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.LaplacianOfGaussian));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Prewitt));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.RobertsCross));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Robinson));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Scharr));
+ this.image.Mutate(x => x.DetectEdges(KnownEdgeDetectorKernels.Sobel));
}
}
}
diff --git a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs
index fd41a04e2..e14ab748f 100644
--- a/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs
+++ b/tests/ImageSharp.Tests/Processing/Convolution/DetectEdgesTest.cs
@@ -1,12 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
-using System.Collections.Generic;
-
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Convolution;
-using SixLabors.ImageSharp.Tests.TestUtilities;
-
using Xunit;
namespace SixLabors.ImageSharp.Tests.Processing.Convolution
@@ -14,62 +10,190 @@ namespace SixLabors.ImageSharp.Tests.Processing.Convolution
public class DetectEdgesTest : BaseImageOperationsExtensionTest
{
[Fact]
- public void DetectEdges_SobelProcessorDefaultsSet()
+ public void DetectEdges_EdgeDetector2DProcessorDefaultsSet()
{
this.operations.DetectEdges();
+ EdgeDetector2DProcessor processor = this.Verify();
- // TODO: Enable once we have updated the images
- SobelProcessor processor = this.Verify();
Assert.True(processor.Grayscale);
+ Assert.Equal(KnownEdgeDetectorKernels.Sobel, processor.Kernel);
}
[Fact]
- public void DetectEdges_Rect_SobelProcessorDefaultsSet()
+ public void DetectEdges_Rect_EdgeDetector2DProcessorDefaultsSet()
{
this.operations.DetectEdges(this.rect);
+ EdgeDetector2DProcessor processor = this.Verify(this.rect);
+
+ Assert.True(processor.Grayscale);
+ Assert.Equal(KnownEdgeDetectorKernels.Sobel, processor.Kernel);
+ }
+
+ public static TheoryData EdgeDetector2DKernelData =
+ new TheoryData
+ {
+ { KnownEdgeDetectorKernels.Kayyali, true },
+ { KnownEdgeDetectorKernels.Kayyali, false },
+ { KnownEdgeDetectorKernels.Prewitt, true },
+ { KnownEdgeDetectorKernels.Prewitt, false },
+ { KnownEdgeDetectorKernels.RobertsCross, true },
+ { KnownEdgeDetectorKernels.RobertsCross, false },
+ { KnownEdgeDetectorKernels.Scharr, true },
+ { KnownEdgeDetectorKernels.Scharr, false },
+ { KnownEdgeDetectorKernels.Sobel, true },
+ { KnownEdgeDetectorKernels.Sobel, false },
+ };
+
+ [Theory]
+ [MemberData(nameof(EdgeDetector2DKernelData))]
+ public void DetectEdges_EdgeDetector2DProcessor_DefaultGrayScale_Set(EdgeDetector2DKernel kernel, bool _)
+ {
+ this.operations.DetectEdges(kernel);
+ EdgeDetector2DProcessor processor = this.Verify();
+
+ Assert.True(processor.Grayscale);
+ Assert.Equal(kernel, processor.Kernel);
+ }
+
+ [Theory]
+ [MemberData(nameof(EdgeDetector2DKernelData))]
+ public void DetectEdges_Rect_EdgeDetector2DProcessor_DefaultGrayScale_Set(EdgeDetector2DKernel kernel, bool _)
+ {
+ this.operations.DetectEdges(kernel, this.rect);
+ EdgeDetector2DProcessor processor = this.Verify(this.rect);
+
+ Assert.True(processor.Grayscale);
+ Assert.Equal(kernel, processor.Kernel);
+ }
+
+ [Theory]
+ [MemberData(nameof(EdgeDetector2DKernelData))]
+ public void DetectEdges_EdgeDetector2DProcessorSet(EdgeDetector2DKernel kernel, bool grayscale)
+ {
+ this.operations.DetectEdges(kernel, grayscale);
+ EdgeDetector2DProcessor processor = this.Verify();
+
+ Assert.Equal(grayscale, processor.Grayscale);
+ Assert.Equal(kernel, processor.Kernel);
+ }
+
+ [Theory]
+ [MemberData(nameof(EdgeDetector2DKernelData))]
+ public void DetectEdges_Rect_EdgeDetector2DProcessorSet(EdgeDetector2DKernel kernel, bool grayscale)
+ {
+ this.operations.DetectEdges(kernel, grayscale, this.rect);
+ EdgeDetector2DProcessor processor = this.Verify(this.rect);
+
+ Assert.Equal(grayscale, processor.Grayscale);
+ Assert.Equal(kernel, processor.Kernel);
+ }
+
+ public static TheoryData EdgeDetectorKernelData =
+ new TheoryData
+ {
+ { KnownEdgeDetectorKernels.Laplacian3x3, true },
+ { KnownEdgeDetectorKernels.Laplacian3x3, false },
+ { KnownEdgeDetectorKernels.Laplacian5x5, true },
+ { KnownEdgeDetectorKernels.Laplacian5x5, false },
+ { KnownEdgeDetectorKernels.LaplacianOfGaussian, true },
+ { KnownEdgeDetectorKernels.LaplacianOfGaussian, false },
+ };
+
+ [Theory]
+ [MemberData(nameof(EdgeDetectorKernelData))]
+ public void DetectEdges_EdgeDetectorProcessor_DefaultGrayScale_Set(EdgeDetectorKernel kernel, bool _)
+ {
+ this.operations.DetectEdges(kernel);
+ EdgeDetectorProcessor processor = this.Verify();
- // TODO: Enable once we have updated the images
- SobelProcessor processor = this.Verify(this.rect);
Assert.True(processor.Grayscale);
+ Assert.Equal(kernel, processor.Kernel);
}
- public static IEnumerable