From b3632b1de77146af6cb049b5fdb012d0bb0de40b Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Wed, 31 Aug 2022 19:51:46 +0200 Subject: [PATCH 1/5] Fix issue #2217 --- .../AdaptiveThresholdProcessor{TPixel}.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs index c0df16a66a..ecbec84e31 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs @@ -133,19 +133,21 @@ public void Invoke(int y) { Rgba32 rgb = default; Span pixelRow = this.source.DangerousGetRowSpan(y); + int maxX = this.bounds.Width - 1; + int maxY = this.bounds.Height - 1; for (int x = this.startX; x < this.endX; x++) { TPixel pixel = pixelRow[x]; pixel.ToRgba32(ref rgb); - var x1 = Math.Max(x - this.startX - this.clusterSize + 1, 0); - var x2 = Math.Min(x - this.startX + this.clusterSize + 1, this.bounds.Width - 1); - var y1 = Math.Max(y - this.startY - this.clusterSize + 1, 0); - var y2 = Math.Min(y - this.startY + this.clusterSize + 1, this.bounds.Height - 1); + int x1 = Math.Min(Math.Max(x - this.startX - this.clusterSize + 1, 0), maxX); + int x2 = Math.Min(x - this.startX + this.clusterSize + 1, maxX); + int y1 = Math.Min(Math.Max(y - this.startY - this.clusterSize + 1, 0), maxY); + int y2 = Math.Min(y - this.startY + this.clusterSize + 1, maxY); - var count = (uint)((x2 - x1) * (y2 - y1)); - var sum = (long)Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], long.MaxValue); + uint count = (uint)((x2 - x1) * (y2 - y1)); + long sum = (long)Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], long.MaxValue); if ((rgb.R + rgb.G + rgb.B) * count <= sum * this.thresholdLimit) { From 3c2f8bfe33c81fa1718c896d7585eabf37cb578e Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Wed, 31 Aug 2022 20:04:34 +0200 Subject: [PATCH 2/5] Add test for #2217 --- .../Binarization/AdaptiveThresholdTests.cs | 16 ++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 3 +++ .../Issue_2217_AdaptiveThresholdProcessor.png | 3 +++ 3 files changed, 22 insertions(+) create mode 100644 tests/Images/Input/Png/issues/Issue_2217_AdaptiveThresholdProcessor.png diff --git a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs index 88ad03949f..5c725dbf02 100644 --- a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs +++ b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Binarization; @@ -125,5 +126,20 @@ public void AdaptiveThreshold_WithRectangle_Works(TestImageProvider( + TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + Exception exception = Record.Exception(() => + { + using Image image = provider.GetImage(); + }); + + Assert.Null(exception); + } } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 306a28dae9..082ba9e03c 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -125,6 +125,9 @@ public static class Png // Discussion 1875: https://github.com/SixLabors/ImageSharp/discussions/1875 public const string Issue1875 = "Png/raw-profile-type-exif.png"; + // Issue 2217: https://github.com/SixLabors/ImageSharp/issues/2217 + public const string Issue2217 = "Png/issues/Issue_2217_AdaptiveThresholdProcessor.png"; + public static class Bad { public const string MissingDataChunk = "Png/xdtn0g01.png"; diff --git a/tests/Images/Input/Png/issues/Issue_2217_AdaptiveThresholdProcessor.png b/tests/Images/Input/Png/issues/Issue_2217_AdaptiveThresholdProcessor.png new file mode 100644 index 0000000000..c8a364782b --- /dev/null +++ b/tests/Images/Input/Png/issues/Issue_2217_AdaptiveThresholdProcessor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0516beb3860c464e9d7bb2e9da678f0ef9bdb5643eeb1675323d5693546c6646 +size 251 From dac8f712f060aa308079c39cedcf8eea56ab1cbd Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 2 Sep 2022 11:20:08 +1000 Subject: [PATCH 3/5] Fix sampling and optimize. --- .../ProcessingExtensions.IntegralImage.cs | 52 +++++++-- .../AdaptiveThresholdProcessor{TPixel}.cs | 104 +++++------------- .../Binarization/AdaptiveThresholdTests.cs | 2 + .../Processing/IntegralImageTests.cs | 53 ++++++++- ...d_WithRectangle_Works_Rgba32_Bradley02.png | 4 +- ...aptiveThreshold_Works_Rgba32_Bradley01.png | 4 +- ...aptiveThreshold_Works_Rgba32_Bradley02.png | 4 +- .../AdaptiveThreshold_Works_Rgba32_ducky.png | 4 +- 8 files changed, 134 insertions(+), 93 deletions(-) diff --git a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs index ed30c36e72..deed044543 100644 --- a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs +++ b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.IntegralImage.cs @@ -22,26 +22,60 @@ public static partial class ProcessingExtensions /// The containing all the sums. public static Buffer2D CalculateIntegralImage(this Image source) where TPixel : unmanaged, IPixel + => CalculateIntegralImage(source.Frames.RootFrame); + + /// + /// Apply an image integral. + /// + /// The image on which to apply the integral. + /// The bounds within the image frame to calculate. + /// The type of the pixel. + /// The containing all the sums. + public static Buffer2D CalculateIntegralImage(this Image source, Rectangle bounds) + where TPixel : unmanaged, IPixel + => CalculateIntegralImage(source.Frames.RootFrame, bounds); + + /// + /// Apply an image integral. + /// + /// The image frame on which to apply the integral. + /// The type of the pixel. + /// The containing all the sums. + public static Buffer2D CalculateIntegralImage(this ImageFrame source) + where TPixel : unmanaged, IPixel + => source.CalculateIntegralImage(source.Bounds()); + + /// + /// Apply an image integral. + /// + /// The image frame on which to apply the integral. + /// The bounds within the image frame to calculate. + /// The type of the pixel. + /// The containing all the sums. + public static Buffer2D CalculateIntegralImage(this ImageFrame source, Rectangle bounds) + where TPixel : unmanaged, IPixel { Configuration configuration = source.GetConfiguration(); - int endY = source.Height; - int endX = source.Width; + var interest = Rectangle.Intersect(bounds, source.Bounds()); + int startY = interest.Y; + int startX = interest.X; + int endY = interest.Height; - Buffer2D intImage = configuration.MemoryAllocator.Allocate2D(source.Width, source.Height); + Buffer2D intImage = configuration.MemoryAllocator.Allocate2D(interest.Width, interest.Height); ulong sumX0 = 0; - Buffer2D sourceBuffer = source.Frames.RootFrame.PixelBuffer; + Buffer2D sourceBuffer = source.PixelBuffer; - using (IMemoryOwner tempRow = configuration.MemoryAllocator.Allocate(source.Width)) + using (IMemoryOwner tempRow = configuration.MemoryAllocator.Allocate(interest.Width)) { Span tempSpan = tempRow.GetSpan(); - Span sourceRow = sourceBuffer.DangerousGetRowSpan(0); + Span sourceRow = sourceBuffer.DangerousGetRowSpan(startY).Slice(startX, tempSpan.Length); Span destRow = intImage.DangerousGetRowSpan(0); PixelOperations.Instance.ToL8(configuration, sourceRow, tempSpan); // First row - for (int x = 0; x < endX; x++) + for (int x = 0; x < tempSpan.Length; x++) { sumX0 += tempSpan[x].PackedValue; destRow[x] = sumX0; @@ -52,7 +86,7 @@ public static Buffer2D CalculateIntegralImage(this Image // All other rows for (int y = 1; y < endY; y++) { - sourceRow = sourceBuffer.DangerousGetRowSpan(y); + sourceRow = sourceBuffer.DangerousGetRowSpan(y + startY).Slice(startX, tempSpan.Length); destRow = intImage.DangerousGetRowSpan(y); PixelOperations.Instance.ToL8(configuration, sourceRow, tempSpan); @@ -62,7 +96,7 @@ public static Buffer2D CalculateIntegralImage(this Image destRow[0] = sumX0 + previousDestRow[0]; // Process all other colmns - for (int x = 1; x < endX; x++) + for (int x = 1; x < tempSpan.Length; x++) { sumX0 += tempSpan[x].PackedValue; destRow[x] = sumX0 + previousDestRow[x]; diff --git a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs index ecbec84e31..e7c5ad4719 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -27,70 +26,33 @@ internal class AdaptiveThresholdProcessor : ImageProcessor /// The source area to process for the current processor instance. public AdaptiveThresholdProcessor(Configuration configuration, AdaptiveThresholdProcessor definition, Image source, Rectangle sourceRectangle) : base(configuration, source, sourceRectangle) - { - this.definition = definition; - } + => this.definition = definition; /// protected override void OnFrameApply(ImageFrame source) { - var intersect = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); + var interest = Rectangle.Intersect(this.SourceRectangle, source.Bounds()); Configuration configuration = this.Configuration; TPixel upper = this.definition.Upper.ToPixel(); TPixel lower = this.definition.Lower.ToPixel(); float thresholdLimit = this.definition.ThresholdLimit; - int startY = intersect.Y; - int endY = intersect.Bottom; - int startX = intersect.X; - int endX = intersect.Right; - - int width = intersect.Width; - int height = intersect.Height; - - // ClusterSize defines the size of cluster to used to check for average. Tweaked to support up to 4k wide pixels and not more. 4096 / 16 is 256 thus the '-1' - byte clusterSize = (byte)Math.Truncate((width / 16f) - 1); - - Buffer2D sourceBuffer = source.PixelBuffer; - - // Using pooled 2d buffer for integer image table and temp memory to hold Rgb24 converted pixel data. - using (Buffer2D intImage = this.Configuration.MemoryAllocator.Allocate2D(width, height)) - { - Rgba32 rgb = default; - for (int x = startX; x < endX; x++) - { - ulong sum = 0; - for (int y = startY; y < endY; y++) - { - Span row = sourceBuffer.DangerousGetRowSpan(y); - ref TPixel rowRef = ref MemoryMarshal.GetReference(row); - ref TPixel color = ref Unsafe.Add(ref rowRef, x); - color.ToRgba32(ref rgb); + // ClusterSize defines the size of cluster to used to check for average. + // Tweaked to support up to 4k wide pixels and not more. 4096 / 16 is 256 thus the '-1' + byte clusterSize = (byte)Math.Clamp(interest.Width / 16F, 0, 255); - sum += (ulong)(rgb.R + rgb.G + rgb.B); - - if (x - startX != 0) - { - intImage[x - startX, y - startY] = intImage[x - startX - 1, y - startY] + sum; - } - else - { - intImage[x - startX, y - startY] = sum; - } - } - } - - var operation = new RowOperation(intersect, source.PixelBuffer, intImage, upper, lower, thresholdLimit, clusterSize, startX, endX, startY); - ParallelRowIterator.IterateRows( - configuration, - intersect, - in operation); - } + using Buffer2D intImage = source.CalculateIntegralImage(interest); + RowOperation operation = new(configuration, interest, source.PixelBuffer, intImage, upper, lower, thresholdLimit, clusterSize); + ParallelRowIterator.IterateRows( + configuration, + interest, + in operation); } - private readonly struct RowOperation : IRowOperation + private readonly struct RowOperation : IRowOperation { + private readonly Configuration configuration; private readonly Rectangle bounds; private readonly Buffer2D source; private readonly Buffer2D intImage; @@ -98,64 +60,58 @@ protected override void OnFrameApply(ImageFrame source) private readonly TPixel lower; private readonly float thresholdLimit; private readonly int startX; - private readonly int endX; private readonly int startY; private readonly byte clusterSize; [MethodImpl(InliningOptions.ShortMethod)] public RowOperation( + Configuration configuration, Rectangle bounds, Buffer2D source, Buffer2D intImage, TPixel upper, TPixel lower, float thresholdLimit, - byte clusterSize, - int startX, - int endX, - int startY) + byte clusterSize) { + this.configuration = configuration; this.bounds = bounds; + this.startX = bounds.X; + this.startY = bounds.Y; this.source = source; this.intImage = intImage; this.upper = upper; this.lower = lower; this.thresholdLimit = thresholdLimit; - this.startX = startX; - this.endX = endX; - this.startY = startY; this.clusterSize = clusterSize; } /// [MethodImpl(InliningOptions.ShortMethod)] - public void Invoke(int y) + public void Invoke(int y, Span span) { - Rgba32 rgb = default; - Span pixelRow = this.source.DangerousGetRowSpan(y); + Span rowSpan = this.source.DangerousGetRowSpan(y).Slice(this.startX, span.Length); + PixelOperations.Instance.ToL8(this.configuration, rowSpan, span); + int maxX = this.bounds.Width - 1; int maxY = this.bounds.Height - 1; - - for (int x = this.startX; x < this.endX; x++) + for (int x = 0; x < rowSpan.Length; x++) { - TPixel pixel = pixelRow[x]; - pixel.ToRgba32(ref rgb); - - int x1 = Math.Min(Math.Max(x - this.startX - this.clusterSize + 1, 0), maxX); - int x2 = Math.Min(x - this.startX + this.clusterSize + 1, maxX); - int y1 = Math.Min(Math.Max(y - this.startY - this.clusterSize + 1, 0), maxY); + int x1 = Math.Clamp(x - this.clusterSize + 1, 0, maxX); + int x2 = Math.Min(x + this.clusterSize + 1, maxX); + int y1 = Math.Clamp(y - this.startY - this.clusterSize + 1, 0, maxY); int y2 = Math.Min(y - this.startY + this.clusterSize + 1, maxY); uint count = (uint)((x2 - x1) * (y2 - y1)); - long sum = (long)Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], long.MaxValue); + ulong sum = Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], ulong.MaxValue); - if ((rgb.R + rgb.G + rgb.B) * count <= sum * this.thresholdLimit) + if (span[x].PackedValue * count <= sum * this.thresholdLimit) { - this.source[x, y] = this.lower; + rowSpan[x] = this.lower; } else { - this.source[x, y] = this.upper; + rowSpan[x] = this.upper; } } } diff --git a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs index 5c725dbf02..c7378bac90 100644 --- a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs +++ b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs @@ -137,6 +137,8 @@ public void Issue_2217_AdaptiveThreshold_DoesNotThrowIndexOutOfRangeException { using Image image = provider.GetImage(); + image.Mutate(img => img.AdaptiveThreshold(.5F)); + image.DebugSave(provider); }); Assert.Null(exception); diff --git a/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs index 330b95a6c6..89d8e5330c 100644 --- a/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs +++ b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs @@ -32,6 +32,30 @@ public void CalculateIntegralImage_Rgba32Works(TestImageProvider provide }); } + [Theory] + [WithFile(TestImages.Png.Bradley01, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Bradley02, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Ducky, PixelTypes.Rgba32)] + public void CalculateIntegralImage_WithBounds_Rgba32Works(TestImageProvider provider) + { + using Image image = provider.GetImage(); + + Rectangle interest = new(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + + // Act: + Buffer2D integralBuffer = image.CalculateIntegralImage(interest); + + // Assert: + VerifySumValues(provider, integralBuffer, interest, (Rgba32 pixel) => + { + L8 outputPixel = default; + + outputPixel.FromRgba32(pixel); + + return outputPixel.PackedValue; + }); + } + [Theory] [WithFile(TestImages.Png.Bradley01, PixelTypes.L8)] [WithFile(TestImages.Png.Bradley02, PixelTypes.L8)] @@ -43,16 +67,41 @@ public void CalculateIntegralImage_L8Works(TestImageProvider provider) Buffer2D integralBuffer = image.CalculateIntegralImage(); // Assert: - VerifySumValues(provider, integralBuffer, (L8 pixel) => { return pixel.PackedValue; }); + VerifySumValues(provider, integralBuffer, (L8 pixel) => pixel.PackedValue); } + [Theory] + [WithFile(TestImages.Png.Bradley01, PixelTypes.L8)] + [WithFile(TestImages.Png.Bradley02, PixelTypes.L8)] + public void CalculateIntegralImage_WithBounds_L8Works(TestImageProvider provider) + { + using Image image = provider.GetImage(); + + Rectangle interest = new(image.Width / 4, image.Height / 4, image.Width / 2, image.Height / 2); + + // Act: + Buffer2D integralBuffer = image.CalculateIntegralImage(interest); + + // Assert: + VerifySumValues(provider, integralBuffer, interest, (L8 pixel) => pixel.PackedValue); + } + + private static void VerifySumValues( + TestImageProvider provider, + Buffer2D integralBuffer, + System.Func getPixel) + where TPixel : unmanaged, IPixel + => VerifySumValues(provider, integralBuffer, integralBuffer.Bounds(), getPixel); + private static void VerifySumValues( TestImageProvider provider, Buffer2D integralBuffer, + Rectangle bounds, System.Func getPixel) where TPixel : unmanaged, IPixel { - Image image = provider.GetImage(); + // Image image = provider.GetImage(); + Buffer2DRegion image = provider.GetImage().GetRootFramePixelBuffer().GetRegion(bounds); // Check top-left corner Assert.Equal(getPixel(image[0, 0]), integralBuffer[0, 0]); diff --git a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_WithRectangle_Works_Rgba32_Bradley02.png b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_WithRectangle_Works_Rgba32_Bradley02.png index ea5a333e82..94d50e1ad8 100644 --- a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_WithRectangle_Works_Rgba32_Bradley02.png +++ b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_WithRectangle_Works_Rgba32_Bradley02.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:36f60abb0ade0320779e242716c61b6dbabc8243a125f0a3145be35e233e117c -size 24542 +oid sha256:5745f61e9b8cd49066b347605deee6dcde17690b9dc0f675466df6b2db706bd6 +size 22348 diff --git a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley01.png b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley01.png index 62660ef4b6..5e53399d73 100644 --- a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley01.png +++ b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley01.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c4a92f0ecd0f2ec06b12091b14f2d421605ef178092bf4f7f7cb4e661270945 -size 52876 +oid sha256:7a767913020c3924f0a7ae95b20c064993a2fcdc3007610df6abe6f34c194ef8 +size 1644 diff --git a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley02.png b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley02.png index 7c40f64c0b..97a594cf61 100644 --- a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley02.png +++ b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Bradley02.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c6d99bcaefa9e344e602465d08714f628b165e7783f73ddb3316e31c3f679825 -size 5760 +oid sha256:e02f5e94b9251be80250926678a2d8bc05318f40c3eff98204e74312ffbca138 +size 2239 diff --git a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_ducky.png b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_ducky.png index 467206ea69..5c19a84215 100644 --- a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_ducky.png +++ b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_ducky.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6826d39280ffd36f075e52cd055975748fedec25a4b58c148b623a6dc6a517f4 -size 2040 +oid sha256:fdd84a24f616d7f06f78ebca01540b59cf1cf8564f442548fe4c8ede6dc1d412 +size 757 From 34371c7a7599450d68865b713e1f7856dbf0dfdd Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 2 Sep 2022 11:38:18 +1000 Subject: [PATCH 4/5] Cleanup --- .../Processing/Binarization/AdaptiveThresholdTests.cs | 2 +- tests/ImageSharp.Tests/Processing/IntegralImageTests.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs index c7378bac90..6f4214c141 100644 --- a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs +++ b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs @@ -137,7 +137,7 @@ public void Issue_2217_AdaptiveThreshold_DoesNotThrowIndexOutOfRangeException { using Image image = provider.GetImage(); - image.Mutate(img => img.AdaptiveThreshold(.5F)); + image.Mutate(img => img.AdaptiveThreshold()); image.DebugSave(provider); }); diff --git a/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs index 89d8e5330c..869f577f79 100644 --- a/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs +++ b/tests/ImageSharp.Tests/Processing/IntegralImageTests.cs @@ -100,7 +100,6 @@ private static void VerifySumValues( System.Func getPixel) where TPixel : unmanaged, IPixel { - // Image image = provider.GetImage(); Buffer2DRegion image = provider.GetImage().GetRootFramePixelBuffer().GetRegion(bounds); // Check top-left corner From 098a4ae7c000268719bc70975aa0b28b19611ff1 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 2 Sep 2022 12:16:07 +0200 Subject: [PATCH 5/5] Compare Issue 2217 to reference output --- .../Binarization/AdaptiveThresholdTests.cs | 19 +------------------ ..._Issue_2217_AdaptiveThresholdProcessor.png | 3 +++ 2 files changed, 4 insertions(+), 18 deletions(-) create mode 100644 tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Issue_2217_AdaptiveThresholdProcessor.png diff --git a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs index 6f4214c141..e9304299d1 100644 --- a/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs +++ b/tests/ImageSharp.Tests/Processing/Binarization/AdaptiveThresholdTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Binarization; @@ -103,6 +102,7 @@ public void AdaptiveThreshold_SettingUpperLowerWithThresholdLimit_WithRectangle_ [WithFile(TestImages.Png.Bradley01, PixelTypes.Rgba32)] [WithFile(TestImages.Png.Bradley02, PixelTypes.Rgba32)] [WithFile(TestImages.Png.Ducky, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Issue2217, PixelTypes.Rgba32)] public void AdaptiveThreshold_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -126,22 +126,5 @@ public void AdaptiveThreshold_WithRectangle_Works(TestImageProvider( - TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - Exception exception = Record.Exception(() => - { - using Image image = provider.GetImage(); - image.Mutate(img => img.AdaptiveThreshold()); - image.DebugSave(provider); - }); - - Assert.Null(exception); - } } } diff --git a/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Issue_2217_AdaptiveThresholdProcessor.png b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Issue_2217_AdaptiveThresholdProcessor.png new file mode 100644 index 0000000000..046dec8e55 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/AdaptiveThresholdTests/AdaptiveThreshold_Works_Rgba32_Issue_2217_AdaptiveThresholdProcessor.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9e47d328e9d6d37a5bf090d2f8d748b80d78be936df06f4b3afec0fd9712f39 +size 412