From c67a3002028c90e5d67622b822a9f0e2c0f41893 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 11 Aug 2016 14:14:31 +1000 Subject: [PATCH] Sanitize binary thresholding. Former-commit-id: fc6a87c6975f8c3583d41bcfc74982e5eb0e6959 Former-commit-id: 018c30dd19b80cb338cb51c9dffbec22b6300fbf Former-commit-id: 9315fed7147852e55aaab74b4f84fb075002d445 --- .../Binarization/BinaryThresholdProcessor.cs | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs b/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs index 029f9c3b33..02b7def4a7 100644 --- a/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs +++ b/src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs @@ -5,11 +5,12 @@ namespace ImageProcessorCore.Processors { + using System; using System.Threading.Tasks; /// /// An to perform binary threshold filtering against an - /// . The image will be converted to Grayscale before thresholding occurs. + /// . The image will be converted to grayscale before thresholding occurs. /// /// The pixel format. /// The packed format. long, float. @@ -18,7 +19,7 @@ namespace ImageProcessorCore.Processors where TP : struct { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The threshold to split the image. Must be between 0 and 1. /// @@ -45,12 +46,12 @@ namespace ImageProcessorCore.Processors public float Value { get; } /// - /// The color to use for pixels that are above the threshold. + /// Gets or sets the color to use for pixels that are above the threshold. /// public T UpperColor { get; set; } /// - /// The color to use for pixels that fall below the threshold. + /// Gets or sets the color to use for pixels that fall below the threshold. /// public T LowerColor { get; set; } @@ -63,38 +64,50 @@ namespace ImageProcessorCore.Processors /// protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) { - // target.SetPixels(source.Width, source.Height, source.Pixels); - - float threshold = this.Value; T upper = this.UpperColor; T lower = this.LowerColor; - int sourceY = sourceRectangle.Y; - int sourceBottom = sourceRectangle.Bottom; 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; + } + using (IPixelAccessor sourcePixels = source.Lock()) using (IPixelAccessor targetPixels = target.Lock()) { Parallel.For( - startY, - endY, - this.ParallelOptions, - y => - { - if (y >= sourceY && y < sourceBottom) + minY, + maxY, + this.ParallelOptions, + y => { - for (int x = startX; x < endX; x++) + int offsetY = y - startY; + for (int x = minX; x < maxX; x++) { - T color = sourcePixels[x, y]; + int offsetX = x - startX; + T color = sourcePixels[offsetX, offsetY]; // Any channel will do since it's Grayscale. - targetPixels[x, y] = color.ToVector4().X >= threshold ? upper : lower; + targetPixels[offsetX, offsetY] = color.ToVector4().X >= threshold ? upper : lower; } + this.OnRowProcessed(); - } - }); + }); } } }