Browse Source

Sanitize binary thresholding.

Former-commit-id: fc6a87c6975f8c3583d41bcfc74982e5eb0e6959
Former-commit-id: 018c30dd19b80cb338cb51c9dffbec22b6300fbf
Former-commit-id: 9315fed7147852e55aaab74b4f84fb075002d445
af/merge-core
James Jackson-South 10 years ago
parent
commit
c67a300202
  1. 53
      src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs

53
src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs

@ -5,11 +5,12 @@
namespace ImageProcessorCore.Processors
{
using System;
using System.Threading.Tasks;
/// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to perform binary threshold filtering against an
/// <see cref="Image"/>. The image will be converted to Grayscale before thresholding occurs.
/// <see cref="Image"/>. The image will be converted to grayscale before thresholding occurs.
/// </summary>
/// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
@ -18,7 +19,7 @@ namespace ImageProcessorCore.Processors
where TP : struct
{
/// <summary>
/// Initializes a new instance of the <see cref="ThresholdProcessor"/> class.
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor{T,TP}"/> class.
/// </summary>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
/// <exception cref="ArgumentException">
@ -45,12 +46,12 @@ namespace ImageProcessorCore.Processors
public float Value { get; }
/// <summary>
/// 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.
/// </summary>
public T UpperColor { get; set; }
/// <summary>
/// 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.
/// </summary>
public T LowerColor { get; set; }
@ -63,38 +64,50 @@ namespace ImageProcessorCore.Processors
/// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> 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<T, TP> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> 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();
}
});
});
}
}
}

Loading…
Cancel
Save