diff --git a/src/ImageProcessorCore/Image/IImageProcessor.cs b/src/ImageProcessorCore/Image/IImageProcessor.cs index 3942bf1db2..c13f88a9ab 100644 --- a/src/ImageProcessorCore/Image/IImageProcessor.cs +++ b/src/ImageProcessorCore/Image/IImageProcessor.cs @@ -3,10 +3,10 @@ // Licensed under the Apache License, Version 2.0. // -using System.Threading.Tasks; - namespace ImageProcessorCore.Processors { + using System.Threading.Tasks; + /// /// A delegate which is called as progress is made processing an image. /// diff --git a/src/ImageProcessorCore/Image/ImageProcessingExtensions.cs b/src/ImageProcessorCore/Image/ImageProcessingExtensions.cs index 25e41bf28e..e3a0dbd182 100644 --- a/src/ImageProcessorCore/Image/ImageProcessingExtensions.cs +++ b/src/ImageProcessorCore/Image/ImageProcessingExtensions.cs @@ -171,7 +171,9 @@ namespace ImageProcessorCore // Several properties still require copying if (!clone) + { transformedImage.CopyProperties(source); + } action(source, transformedImage); diff --git a/src/ImageProcessorCore/ImageProcessor.cs b/src/ImageProcessorCore/ImageProcessor.cs index 4ec10a6a55..15d4208bec 100644 --- a/src/ImageProcessorCore/ImageProcessor.cs +++ b/src/ImageProcessorCore/ImageProcessor.cs @@ -5,6 +5,7 @@ namespace ImageProcessorCore.Processors { + using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -17,18 +18,13 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - public event ProgressEventHandler OnProgress; - /// - /// The number of rows processed by a derived class. + /// Gets or sets the number of rows processed by a derived class. /// protected int NumRowsProcessed; - /// - /// The total number of rows that will be processed by a derived class. - /// - protected int TotalRows; + /// + public event ProgressEventHandler OnProgress; /// public virtual ParallelOptions ParallelOptions { get; set; } = Bootstrapper.Instance.ParallelOptions; @@ -36,6 +32,11 @@ namespace ImageProcessorCore.Processors /// public virtual bool Compand { get; set; } = false; + /// + /// Gets or sets the total number of rows that will be processed by a derived class. + /// + protected int TotalRows { get; set; } + /// /// Must be called by derived classes after processing a single row. /// diff --git a/src/ImageProcessorCore/Samplers/DetectEdges.cs b/src/ImageProcessorCore/Samplers/DetectEdges.cs index cc45aa05a0..60006ea728 100644 --- a/src/ImageProcessorCore/Samplers/DetectEdges.cs +++ b/src/ImageProcessorCore/Samplers/DetectEdges.cs @@ -25,7 +25,7 @@ namespace ImageProcessorCore where TColor : IPackedVector where TPacked : struct { - return DetectEdges(source, source.Bounds, new SobelProcessor(true), progressHandler); + return DetectEdges(source, source.Bounds, new SobelProcessor { Grayscale = true }, progressHandler); } /// @@ -44,7 +44,7 @@ namespace ImageProcessorCore where TColor : IPackedVector where TPacked : struct { - return DetectEdges(source, rectangle, new SobelProcessor(true), progressHandler); + return DetectEdges(source, rectangle, new SobelProcessor { Grayscale = true }, progressHandler); } /// @@ -86,39 +86,39 @@ namespace ImageProcessorCore switch (filter) { case EdgeDetection.Kayyali: - processor = new KayyaliProcessor(grayscale); + processor = new KayyaliProcessor { Grayscale = grayscale }; break; case EdgeDetection.Kirsch: - processor = new KirschProcessor(grayscale); + processor = new KirschProcessor { Grayscale = grayscale }; break; case EdgeDetection.Lapacian3X3: - processor = new Laplacian3X3Processor(grayscale); + processor = new Laplacian3X3Processor { Grayscale = grayscale }; break; case EdgeDetection.Lapacian5X5: - processor = new Laplacian5X5Processor(grayscale); + processor = new Laplacian5X5Processor { Grayscale = grayscale }; break; case EdgeDetection.LaplacianOfGaussian: - processor = new LaplacianOfGaussianProcessor(grayscale); + processor = new LaplacianOfGaussianProcessor { Grayscale = grayscale }; break; case EdgeDetection.Prewitt: - processor = new PrewittProcessor(grayscale); + processor = new PrewittProcessor { Grayscale = grayscale }; break; case EdgeDetection.RobertsCross: - processor = new RobertsCrossProcessor(grayscale); + processor = new RobertsCrossProcessor { Grayscale = grayscale }; break; case EdgeDetection.Scharr: - processor = new ScharrProcessor(grayscale); + processor = new ScharrProcessor { Grayscale = grayscale }; break; default: - processor = new SobelProcessor(grayscale); + processor = new SobelProcessor { Grayscale = grayscale }; break; } diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs index e107f71a92..d39bcaba65 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs @@ -11,39 +11,27 @@ namespace ImageProcessorCore.Processors /// /// The pixel format. /// The packed format. uint, long, float. - public class EdgeDetector2DFilter : ImageSampler, IEdgeDetectorFilter + public abstract class EdgeDetector2DFilter : ImageSampler, IEdgeDetectorFilter where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// The horizontal gradient operator. - /// The vertical gradient operator. - /// Whether to convert the image to grayscale before performing edge detection.. - public EdgeDetector2DFilter(float[,] kernelX, float[,] kernelY, bool grayscale) - { - this.KernelX = kernelX; - this.KernelY = kernelY; - this.Grayscale = grayscale; - } - /// /// Gets the horizontal gradient operator. /// - public float[,] KernelX { get; } + public abstract float[,] KernelX { get; } /// /// Gets the vertical gradient operator. /// - public float[,] KernelY { get; } + public abstract float[,] KernelY { get; } /// - public bool Grayscale { get; } + public bool Grayscale { get; set; } /// public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { + // TODO: Figure out a way to pass event handlers to child classes. new Convolution2DFilter(this.KernelX, this.KernelY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); } diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs index 060fc837fe..5cb1c3ded4 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorCompassFilter.cs @@ -9,34 +9,63 @@ namespace ImageProcessorCore.Processors using System.Numerics; using System.Threading.Tasks; - public class EdgeDetectorCompassFilter : ImageSampler, IEdgeDetectorFilter + /// + /// Defines a filter that detects edges within an image using a eight two dimensional matrices. + /// + /// The pixel format. + /// The packed format. uint, long, float. + public abstract class EdgeDetectorCompassFilter : ImageSampler, IEdgeDetectorFilter where TColor : IPackedVector where TPacked : struct { /// - /// Initializes a new instance of the class. + /// Gets the North gradient operator /// - /// - /// The collection of 2d gradient operator. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public EdgeDetectorCompassFilter(float[][,] kernels, bool grayscale) - { - this.Kernels = kernels; - this.Grayscale = grayscale; - } + public abstract float[,] North { get; } /// - /// Gets the collection of 2d gradient operators. + /// Gets the NorthWest gradient operator /// - public float[][,] Kernels { get; } + public abstract float[,] NorthWest { get; } - /// - public bool Grayscale { get; } + /// + /// Gets the West gradient operator + /// + public abstract float[,] West { get; } + + /// + /// Gets the SouthWest gradient operator + /// + public abstract float[,] SouthWest { get; } + + /// + /// Gets the South gradient operator + /// + public abstract float[,] South { get; } + + /// + /// Gets the SouthEast gradient operator + /// + public abstract float[,] SouthEast { get; } + + /// + /// Gets the East gradient operator + /// + public abstract float[,] East { get; } + + /// + /// Gets the NorthEast gradient operator + /// + public abstract float[,] NorthEast { get; } + + /// + public bool Grayscale { get; set; } /// public override void Apply(ImageBase target, ImageBase 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 }; + int startX = sourceRectangle.X; int endX = sourceRectangle.Right; @@ -46,34 +75,33 @@ namespace ImageProcessorCore.Processors int minY = Math.Max(0, startY); int maxY = Math.Min(source.Height, endY); - // Reset offset if necessary. - if (minX > 0) - { - startX = 0; - } + // First run. + new ConvolutionFilter(kernels[0]).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); - if (minY > 0) + if (kernels.Length == 1) { - startY = 0; + return; } + int shiftY = startY; + int shiftX = startX; - new EdgeDetectorFilter(this.Kernels[0], this.Grayscale).Apply(target, source, sourceRectangle, targetRectangle, startY, endY); - - //this.ApplyConvolution(target, source, sourceRectangle, this.Grayscale, this.Kernels[0]); + // Reset offset if necessary. + if (minX > 0) + { + shiftX = 0; + } - if (this.Kernels.Length == 1) + if (minY > 0) { - return; + shiftY = 0; } - for (int i = 1; i < this.Kernels.Length; i++) + // Additional runs. + for (int i = 1; i < kernels.Length; i++) { ImageBase pass = new Image(source.Width, source.Height); - new EdgeDetectorFilter(this.Kernels[0], false).Apply(pass, source, sourceRectangle, targetRectangle, startY, endY); - - - // this.ApplyConvolution(pass, source, sourceRectangle, false, this.Kernels[0]); + new ConvolutionFilter(kernels[i]).Apply(pass, source, sourceRectangle, targetRectangle, startY, endY); using (PixelAccessor passPixels = pass.Lock()) using (PixelAccessor targetPixels = target.Lock()) @@ -84,15 +112,14 @@ namespace ImageProcessorCore.Processors this.ParallelOptions, y => { - int offsetY = y - startY; + int offsetY = y - shiftY; for (int x = minX; x < maxX; x++) { - int offsetX = x - startX; - Vector4 passColor = passPixels[offsetX, offsetY].ToVector4(); - Vector4 targetColor = targetPixels[offsetX, offsetY].ToVector4(); + int offsetX = x - shiftX; + // Grab the max components of the two pixels TColor packed = default(TColor); - packed.PackFromVector4(Vector4.Max(passColor, targetColor)); + packed.PackFromVector4(Vector4.Max(passPixels[offsetX, offsetY].ToVector4(), targetPixels[offsetX, offsetY].ToVector4())); targetPixels[offsetX, offsetY] = packed; } }); @@ -108,21 +135,5 @@ namespace ImageProcessorCore.Processors new GrayscaleBt709Processor().Apply(source, sourceRectangle); } } - - /// - /// Applies the convolution process to the specified portion of the specified at the specified location - /// and with the specified size. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// Whether to convert the image to grayscale before performing edge detection. - /// The kernel operator. - private void ApplyConvolution(ImageBase target, ImageBase source, Rectangle sourceRectangle, bool grayScale, float[,] kernel) - { - new EdgeDetectorFilter(kernel, grayScale).Apply(target, source, sourceRectangle); - } } -} +} \ No newline at end of file diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs index 8a43f26f27..93956a6f16 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs @@ -6,28 +6,27 @@ namespace ImageProcessorCore.Processors { /// - /// Defines a filter that detects edges within an image using a single - /// two dimensional matrix. + /// Defines a filter that detects edges within an image using a single two dimensional matrix. /// /// The pixel format. /// The packed format. uint, long, float. - public class EdgeDetectorFilter : ConvolutionFilter, IEdgeDetectorFilter + public abstract class EdgeDetectorFilter : ImageSampler, IEdgeDetectorFilter where TColor : IPackedVector where TPacked : struct { + /// + public bool Grayscale { get; set; } + /// - /// Initializes a new instance of the class. + /// Gets the 2d gradient operator. /// - /// The 2d gradient operator. - /// Whether to convert the image to grayscale before performing edge detection.. - public EdgeDetectorFilter(float[,] kernelXY, bool grayscale) - : base(kernelXY) - { - this.Grayscale = grayscale; - } + public abstract float[,] KernelXY { get; } /// - public bool Grayscale { get; } + public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) + { + new ConvolutionFilter(this.KernelXY).Apply(target, source, targetRectangle, sourceRectangle, startY, endY); + } /// protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs index 76039e5e60..d040743e8f 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs @@ -22,9 +22,8 @@ namespace ImageProcessorCore.Processors public interface IEdgeDetectorFilter { /// - /// Gets a value indicating whether to convert the - /// image to grayscale before performing edge detection. + /// Gets or sets a value indicating whether to convert the image to grayscale before performing edge detection. /// - bool Grayscale { get; } + bool Grayscale { get; set; } } } \ No newline at end of file diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs index 60bebbce71..a7d31a6078 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs @@ -15,29 +15,16 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public KayyaliProcessor(bool grayscale) - : base(KernelA, KernelB, grayscale) - { - } - - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelA => new float[,] + /// + public override float[,] KernelX => new float[,] { { 6, 0, -6 }, { 0, 0, 0 }, { -6, 0, 6 } }; - /// - /// Gets the vertical gradient operator. - /// - public static float[,] KernelB => new float[,] + /// + public override float[,] KernelY => new float[,] { { -6, 0, 6 }, { 0, 0, 0 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs index 908a3781bb..30d39007c7 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/KirschProcessor.cs @@ -15,96 +15,68 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - public KirschProcessor(bool grayscale) - : base(new[] { North, Northwest, West, Southwest, South, Southeast, East, Northeast }, grayscale) + /// + public override float[,] North => new float[,] { - } - - /// - /// Gets the North direction Kirsch kernel mask. - /// - /// - public static float[,] North => new float[,] - { - { -3, -3, 5 }, - { -3, 0, 5 }, - { -3, -3, 5 } - }; - - /// - /// Gets the Northwest direction Kirsch kernel mask. - /// - /// - public static float[,] Northwest => new float[,] - { - { -3, 5, 5 }, - { -3, 0, 5 }, - { -3, -3, -3 } - }; - - /// - /// Gets the West direction Kirsch kernel mask. - /// - /// - public static float[,] West => new float[,] - { - { 5, 5, 5 }, + { 5, 5, 5 }, { -3, 0, -3 }, { -3, -3, -3 } }; - /// - /// Gets the Southwest direction Kirsch kernel mask. - /// - /// - public static float[,] Southwest => new float[,] + /// + public override float[,] NorthWest => new float[,] { - { 5, 5, -3 }, - { 5, 0, -3 }, + { 5, 5, -3 }, + { 5, 0, -3 }, { -3, -3, -3 } }; - /// - /// Gets the South direction Kirsch kernel mask. - /// - /// - public static float[,] South => new float[,] + /// + public override float[,] West => new float[,] { - { 5, -3, -3 }, - { 5, 0, -3 }, - { 5, -3, -3 } + { 5, -3, -3 }, + { 5, 0, -3 }, + { 5, -3, -3 } }; - /// - /// Gets the Southeast direction Kirsch kernel mask. - /// - public static float[,] Southeast => new float[,] + /// + public override float[,] SouthWest => new float[,] { { -3, -3, -3 }, { 5, 0, -3 }, { 5, 5, -3 } }; - /// - /// Gets the East direction Kirsch kernel mask. - /// - /// - public static float[,] East => new float[,] + /// + public override float[,] South => new float[,] { { -3, -3, -3 }, { -3, 0, -3 }, { 5, 5, 5 } }; - /// - /// Gets the Northeast direction Kirsch kernel mask. - /// - /// - public static float[,] Northeast => new float[,] + /// + public override float[,] SouthEast => new float[,] { { -3, -3, -3 }, { -3, 0, 5 }, { -3, 5, 5 } }; + + /// + public override float[,] East => new float[,] + { + { -3, -3, 5 }, + { -3, 0, 5 }, + { -3, -3, 5 } + }; + + /// + public override float[,] NorthEast => new float[,] + { + { -3, 5, 5 }, + { -3, 0, 5 }, + { -3, -3, -3 } + }; } -} +} \ No newline at end of file diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs index 19d8a0b4ea..47eb02202b 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs @@ -15,19 +15,8 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public Laplacian3X3Processor(bool grayscale) - : base(Kernel, grayscale) - { - } - - /// - /// Gets the 2d gradient operator. - /// - public static float[,] Kernel => new float[,] + /// + public override float[,] KernelXY => new float[,] { { -1, -1, -1 }, { -1, 8, -1 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs index 583c989933..90367162c2 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs @@ -15,19 +15,8 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public Laplacian5X5Processor(bool grayscale) - : base(Kernel, grayscale) - { - } - - /// - /// Gets the 2d gradient operator. - /// - public static float[,] Kernel => new float[,] + /// + public override float[,] KernelXY => new float[,] { { -1, -1, -1, -1, -1 }, { -1, -1, -1, -1, -1 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs index cbbd7ac95f..ec3bda8fee 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs @@ -15,19 +15,8 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public LaplacianOfGaussianProcessor(bool grayscale) - : base(Kernel, grayscale) - { - } - - /// - /// Gets the 2d gradient operator. - /// - public static float[,] Kernel => new float[,] + /// + public override float[,] KernelXY => new float[,] { { 0, 0, -1, 0, 0 }, { 0, -1, -2, -1, 0 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs index d883d376fb..897ba212e7 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/PrewittProcessor.cs @@ -15,29 +15,16 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public PrewittProcessor(bool grayscale) - : base(KernelA, KernelB, grayscale) - { - } - - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelA => new float[,] + /// + public override float[,] KernelX => new float[,] { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } }; - /// - /// Gets the vertical gradient operator. - /// - public static float[,] KernelB => new float[,] + /// + public override float[,] KernelY => new float[,] { { 1, 1, 1 }, { 0, 0, 0 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs index c21e18c9b9..69c5abe347 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs @@ -15,28 +15,15 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public RobertsCrossProcessor(bool grayscale) - : base(KernelA, KernelB, grayscale) - { - } - - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelA => new float[,] + /// + public override float[,] KernelX => new float[,] { { 1, 0 }, { 0, -1 } }; - /// - /// Gets the vertical gradient operator. - /// - public static float[,] KernelB => new float[,] + /// + public override float[,] KernelY => new float[,] { { 0, 1 }, { -1, 0 } diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs index ca7f584bcc..f860d7cfbb 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/ScharrProcessor.cs @@ -15,29 +15,16 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public ScharrProcessor(bool grayscale) - : base(KernelA, KernelB, grayscale) - { - } - - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelA => new float[,] + /// + public override float[,] KernelX => new float[,] { { -3, 0, 3 }, { -10, 0, 10 }, { -3, 0, 3 } }; - /// - /// Gets the vertical gradient operator. - /// - public static float[,] KernelB => new float[,] + /// + public override float[,] KernelY => new float[,] { { 3, 10, 3 }, { 0, 0, 0 }, diff --git a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs index be22810272..d7f269178d 100644 --- a/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/Convolution/EdgeDetection/SobelProcessor.cs @@ -15,33 +15,20 @@ namespace ImageProcessorCore.Processors where TColor : IPackedVector where TPacked : struct { - /// - /// Initializes a new instance of the class. - /// - /// Whether to convert the image to grayscale before performing edge detection.. - public SobelProcessor(bool grayscale) - : base(KernelA, KernelB, grayscale) - { - } - - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelA => new float[,] + /// + public override float[,] KernelX => new float[,] { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }; - /// - /// Gets the horizontal gradient operator. - /// - public static float[,] KernelB => new float[,] + /// + public override float[,] KernelY => new float[,] { - { 1, 2, 1 }, + { -1, -2, -1 }, { 0, 0, 0 }, - { -1, -2, -1 } + { 1, 2, 1 } }; } } diff --git a/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs index ab097ce057..6d9afb9a5b 100644 --- a/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/EntropyCropProcessor.cs @@ -41,25 +41,6 @@ namespace ImageProcessorCore.Processors /// public float Value { get; } - /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - ImageBase temp = new Image(source.Width, source.Height); - - // Detect the edges. - new SobelProcessor(false).Apply(temp, source, sourceRectangle); - - // Apply threshold binarization filter. - new BinaryThresholdProcessor(.5f).Apply(temp, sourceRectangle); - - // Search for the first white pixels - Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); - - // Reset the target pixel to the correct size. - target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); - this.cropRectangle = rectangle; - } - /// public override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { @@ -96,6 +77,25 @@ namespace ImageProcessorCore.Processors } } + /// + protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) + { + ImageBase temp = new Image(source.Width, source.Height); + + // Detect the edges. + new SobelProcessor().Apply(temp, source, sourceRectangle); + + // Apply threshold binarization filter. + new BinaryThresholdProcessor(.5f).Apply(temp, sourceRectangle); + + // Search for the first white pixels + Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0); + + // Reset the target pixel to the correct size. + target.SetPixels(rectangle.Width, rectangle.Height, new TColor[rectangle.Width * rectangle.Height]); + this.cropRectangle = rectangle; + } + /// protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) { @@ -106,4 +106,4 @@ namespace ImageProcessorCore.Processors } } } -} +} \ No newline at end of file diff --git a/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs b/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs index b2e4890f88..9b21446c7c 100644 --- a/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs +++ b/src/ImageProcessorCore/Samplers/Processors/ImageSampler.cs @@ -32,7 +32,6 @@ namespace ImageProcessorCore.Processors } catch (Exception ex) { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex); } }