From 625ea86dd36ea4a79dab51698bd00b7607dc2d00 Mon Sep 17 00:00:00 2001 From: SimantoR Date: Sat, 13 Oct 2018 04:01:48 -0230 Subject: [PATCH] Added parallelism to loops --- .../AdaptiveThresholdProcessor.cs | 127 +++++++++++------- tests/Images/External | 2 +- 2 files changed, 76 insertions(+), 53 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs index 46e2e67c0d..898e1f8fd7 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor.cs @@ -1,6 +1,11 @@ -using System; +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Threading.Tasks; using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.ParallelUtils; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Memory; using SixLabors.Primitives; @@ -46,80 +51,98 @@ namespace SixLabors.ImageSharp.Processing.Processors /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) { - var interest = Rectangle.Intersect(sourceRectangle, source.Bounds()); - ushort startY = (ushort)interest.Y; - ushort endY = (ushort)interest.Bottom; - ushort startX = (ushort)interest.X; - ushort endX = (ushort)interest.Right; + var intersect = Rectangle.Intersect(sourceRectangle, source.Bounds()); + ushort startY = (ushort)intersect.Y; + ushort endY = (ushort)intersect.Bottom; + ushort startX = (ushort)intersect.X; + ushort endX = (ushort)intersect.Right; ushort width = (ushort)(endX - startX); ushort height = (ushort)(endY - startY); - // Algorithm variables // - ulong sum; - uint count; - - // Tweaked to support upto 4k wide pixels - ushort s = (ushort)Math.Truncate((width / 16f) - 1); + // Tweaked to support upto 4k wide pixels and not more. 4096 / 16 is 256 thus the '-1' + byte s = (byte)Math.Truncate((width / 16f) - 1); - // Trying to figure out how to do this + // Using pooled 2d buffer for integer image table using (Buffer2D intImage = configuration.MemoryAllocator.Allocate2D(width, height, AllocationOptions.Clean)) { - Rgb24 rgb = default; - - for (ushort i = startY; i < endY; i++) - { - Span span = source.GetPixelRowSpan(i); - - sum = 0; + var workingnRectangle = Rectangle.FromLTRB(startX, startY, endX, endY); - for (ushort j = startX; j < endX; j++) + ParallelHelper.IterateRows( + workingnRectangle, + configuration, + rows => { - span[j].ToRgb24(ref rgb); + ulong sum; - sum += (uint)(rgb.R + rgb.G + rgb.B); + Rgb24 rgb = default; - if (i != 0) + for (int i = rows.Min; i < rows.Max; i++) { - intImage[i, j] = intImage[i - 1, j] + sum; - } - else - { - intImage[i, j] = sum; + var row = source.GetPixelRowSpan(i); + + sum = 0; + + for (int j = startX; j < endX; j++) + { + row[j].ToRgb24(ref rgb); + sum += (ulong)(rgb.B + rgb.G + rgb.B); + + if (i != 0) + { + intImage[i, j] = intImage[i - 1, j] + sum; + } + else + { + intImage[i, j] = sum; + } + } } } - } + ); - // How can I parallelize this? - ushort x1, x2, y1, y2; + ParallelHelper.IterateRows( + workingnRectangle, + configuration, + rows => + { + ushort x1, x2, y1, y2; - for (ushort i = startY; i < endY; i++) - { - Span span = source.GetPixelRowSpan(i); + uint count; - for (ushort j = startX; j < endX; j++) - { - x1 = (ushort)Math.Max(i - s + 1, 0); - x2 = (ushort)Math.Min(i + s + 1, endY - 1); - y1 = (ushort)Math.Max(j - s + 1, 0); - y2 = (ushort)Math.Min(j + s + 1, endX - 1); + long sum; - count = (uint)((x2 - x1) * (y2 - y1)); + for (int i = rows.Min; i < rows.Max; i++) + { + var row = source.GetPixelRowSpan(i); - sum = intImage[x2, y2] - intImage[x1, y2] - intImage[x2, y1] + intImage[x1, y1]; + Rgb24 rgb = default; - span[j].ToRgb24(ref rgb); + for (int j = startX; j < endX; j++) + { + x1 = (ushort)Math.Max(i - s + 1, 0); + x2 = (ushort)Math.Min(i + s + 1, endY - 1); + y1 = (ushort)Math.Max(j - s + 1, 0); + y2 = (ushort)Math.Min(j + s + 1, endX - 1); - if ((rgb.R + rgb.G + rgb.B) * count < sum * (1.0 - 0.15)) - { - span[j] = this.Lower; - } - else - { - span[j] = this.Upper; + count = (uint)((x2 - x1) * (y2 - y1)); + + sum = (long)(intImage[x2, y2] - intImage[x1, y2] - intImage[x2, y1] + intImage[x1, y1]); + + row[j].ToRgb24(ref rgb); + + if ((rgb.R + rgb.G + rgb.B) * count < sum * (1.0 - 0.15)) + { + row[j] = this.Lower; + } + else + { + row[j] = this.Upper; + } + } } } - } + ); } } } diff --git a/tests/Images/External b/tests/Images/External index ee90e5f322..5f3cbd839f 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit ee90e5f32218027744b5d40058b587cc1047b76f +Subproject commit 5f3cbd839fbbffae615d294d1dabafdcabc64cf9