Created
March 16, 2017 15:51
-
-
Save tocsoft/5c16a3d57fb3ac3022442d6bce417419 to your computer and use it in GitHub Desktop.
Compare 2 images using ImageSharp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace ImageSharp.Tests | |
{ | |
using System; | |
using ImageSharp; | |
using Xunit; | |
/// <summary> | |
/// Class to perform simple image comparisons. | |
/// </summary> | |
public static class ImageComparer | |
{ | |
const int DefaultScalingFactor = 16; | |
const int DefaultSegmentThreshold = 3; | |
const float DefaultImageThreshold = 0f; | |
public static void VisualComparer<TColorA, TColorB>(Image<TColorA> expected, Image<TColorB> actual, float imageTheshold = DefaultImageThreshold, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) | |
where TColorA : struct, IPixel<TColorA> | |
where TColorB : struct, IPixel<TColorB> | |
{ | |
var percentage = expected.PercentageDifference(actual, segmentThreshold, scalingFactor); | |
Assert.InRange(percentage, 0, imageTheshold); | |
} | |
public static float PercentageDifference<TColorA, TColorB>(this Image<TColorA> source, Image<TColorB> target, byte segmentThreshold = DefaultSegmentThreshold, int scalingFactor = DefaultScalingFactor) | |
where TColorA : struct, IPixel<TColorA> | |
where TColorB : struct, IPixel<TColorB> | |
{ | |
// code adapted from https://www.codeproject.com/Articles/374386/Simple-image-comparison-in-NET | |
Fast2DArray<byte> differences = GetDifferences(source, target, scalingFactor); | |
int diffPixels = 0; | |
foreach (byte b in differences.Data) | |
{ | |
if (b > segmentThreshold) { diffPixels++; } | |
} | |
return diffPixels / 256f; | |
} | |
private static Fast2DArray<byte> GetDifferences<TColorA, TColorB>(Image<TColorA> source, Image<TColorB> target, int scalingFactor) | |
where TColorA : struct, IPixel<TColorA> | |
where TColorB : struct, IPixel<TColorB> | |
{ | |
Fast2DArray<byte> differences = new Fast2DArray<byte>(scalingFactor, scalingFactor); | |
Fast2DArray<byte> firstGray = source.GetGrayScaleValues(scalingFactor); | |
Fast2DArray<byte> secondGray = target.GetGrayScaleValues(scalingFactor); | |
for (int y = 0; y < scalingFactor; y++) | |
{ | |
for (int x = 0; x < scalingFactor; x++) | |
{ | |
differences[x, y] = (byte)Math.Abs(firstGray[x, y] - secondGray[x, y]); | |
} | |
} | |
return differences; | |
} | |
private static Fast2DArray<byte> GetGrayScaleValues<TColorA>(this Image<TColorA> source, int scalingFactor) | |
where TColorA : struct, IPixel<TColorA> | |
{ | |
byte[] buffer = new byte[4]; | |
using (Image<TColorA> img = new Image<TColorA>(source).Resize(scalingFactor, scalingFactor).Grayscale()) | |
{ | |
using (PixelAccessor<TColorA> pixels = img.Lock()) | |
{ | |
Fast2DArray<byte> grayScale = new Fast2DArray<byte>(scalingFactor, scalingFactor); | |
for (int y = 0; y < scalingFactor; y++) | |
{ | |
for (int x = 0; x < scalingFactor; x++) | |
{ | |
pixels[x, y].ToXyzBytes(buffer, 0); | |
grayScale[x, y] = buffer[1]; | |
} | |
} | |
return grayScale; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment