diff --git a/src/ImageSharp/Processing/Contrast/HistogramEqualizationProcessor.cs b/src/ImageSharp/Processing/Contrast/HistogramEqualizationProcessor.cs index 2bacb98ce..23a2d30ba 100644 --- a/src/ImageSharp/Processing/Contrast/HistogramEqualizationProcessor.cs +++ b/src/ImageSharp/Processing/Contrast/HistogramEqualizationProcessor.cs @@ -35,6 +35,26 @@ namespace SixLabors.ImageSharp.Processing.Contrast } } + int min = luminanceLevels - 1; + for (int i = 0; i < histogram.Length - 1; i++) + { + if (histogram[i] != 0) + { + min = i; + break; + } + } + + int max = 0; + for (int i = histogram.Length - 1; i > 0; i--) + { + if (histogram[i] != 0) + { + max = i; + break; + } + } + // calculate the cumulative distribution function double[] cdf = new double[luminanceLevels]; double sum = 0.0d; @@ -54,8 +74,7 @@ namespace SixLabors.ImageSharp.Processing.Contrast TPixel sourcePixel = row[x]; sourcePixel.ToRgb24(ref rgb); int luminance = (int)((.2126F * rgb.R) + (.7152F * rgb.G) + (.0722F * rgb.B)); - byte luminanceEqualized = (byte)(cdf[luminance] * luminance); - + byte luminanceEqualized = (byte)(cdf[luminance] * (luminanceLevels - 1)); row[x].PackFromRgba32(new Rgba32(luminanceEqualized, luminanceEqualized, luminanceEqualized)); } } diff --git a/tests/ImageSharp.Tests/Processing/Contrast/HistogramEqualizationTests.cs b/tests/ImageSharp.Tests/Processing/Contrast/HistogramEqualizationTests.cs new file mode 100644 index 000000000..b5c584a55 --- /dev/null +++ b/tests/ImageSharp.Tests/Processing/Contrast/HistogramEqualizationTests.cs @@ -0,0 +1,66 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Contrast; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Processing.Contrast +{ + public class HistogramEqualizationTests + { + [Fact] + public void HistogramEqualizationTest() + { + // arrange + byte[] pixels = new byte[] + { + 52, 55, 61, 59, 70, 61, 76, 61, + 62, 59, 55, 104, 94, 85, 59, 71, + 63, 65, 66, 113, 144, 104, 63, 72, + 64, 70, 70, 126, 154, 109, 71, 69, + 67, 73, 68, 106, 122, 88, 68, 68, + 68, 79, 60, 79, 77, 66, 58, 75, + 69, 85, 64, 58, 55, 61, 65, 83, + 70, 87, 69, 68, 65, 73, 78, 90 + }; + var image = new Image(8, 8); + for (int y = 0; y < 8; y++) + { + for (int x = 0; x < 8; x++) + { + byte luminance = pixels[y * 8 + x]; + image[x, y] = new Rgba32(luminance, luminance, luminance); + } + } + + byte[] expected = new byte[] + { + 0, 12, 53, 32, 146, 53, 174, 53, + 57, 32, 12, 227, 219, 202, 32, 154, + 65, 85, 93, 239, 251, 227, 65, 158, + 73, 146, 146, 247, 255, 235, 154, 130, + 97, 166, 117, 231, 243, 210, 117, 117, + 117, 190, 36, 190, 178, 93, 20, 170, + 130, 202, 73, 20, 12, 53, 85, 194, + 146, 206, 130, 117, 85, 166, 182, 215 + }; + + // act + image.Mutate(x => x.HistogramEqualization()); + + // assert + for (int y = 0; y < 8; y++) + { + for (int x = 0; x < 8; x++) + { + Rgba32 actual = image[x, y]; + int diff = expected[y * 8 + x] - actual.R; + Assert.True(diff == 0); + int foo = 2; + } + } + } + } +}