public static double MeanSquaredError(Image left, Image right) { GuardImages(left, right); ImagePipeline .FromImage(left) .Raw() .ToBuffer(out var leftBuffer); ImagePipeline .FromImage(right) .Raw() .ToBuffer(out var rightBuffer); if (leftBuffer == null || rightBuffer == null) { throw new SharpSharpException("Failed to load buffers."); } var sumSquared = 0; for (var y = 0; y < left.Height; y++) { for (var x = 0; x < left.Width; x++) { var p1 = leftBuffer[y * left.Height + x]; var p2 = rightBuffer[y * left.Height + x]; var error = p2 - p1; sumSquared += error * error; } } return(sumSquared / (double)(left.Height * left.Width)); }
/// <summary> /// Calculates a 64 bit difference hash. /// </summary> /// <param name="stream"> /// The image stream to hash. /// </param> /// <returns> /// A 64 bit difference hash. /// </returns> public static long HashLong(Stream stream) { const int Width = 9; const int Height = 8; // TODO: allocations ImagePipeline .FromStream(stream) .Resize(new ResizeOptions(Width, Height, Fit.Fill)) .Grayscale() .Normalize() .Raw() .ToBuffer(out var normalized); var bitArray = new BitArray(64); var bit = 0; for (var x = 0; x < Width - 1; x++) { for (var y = 0; y < Height; y++) { bitArray.Set(bit, normalized[y * Height + x] < normalized[y * Height + x + 1]); bit++; } } var array = new byte[8]; bitArray.CopyTo(array, 0); return(BitConverter.ToInt64(array, 0)); }
public static string Fingerprint(Image image) { Guard.NotNull(image, nameof(image)); ImagePipeline .FromImage(image) .ToBuffer(out var buffer); return(Convert.ToString((long)DifferenceHash.HashLong(buffer), 2)); }
/// <summary> /// Calculates a 16 bit difference hash. /// </summary> /// <param name="stream"> /// The image stream to hash. /// </param> /// <returns> /// A 16 bit difference hash. /// </returns> public static short HashShort(Stream stream) { const int Width = 6; const int Height = 4; // TODO: allocations ImagePipeline .FromStream(stream) .Resize(new ResizeOptions { Canvas = Canvas.IgnoreAspectRatio, Height = Height, Width = Width, }) .Grayscale() .Normalize() .Raw() .ToBuffer(out var normalized); var bitArray = new BitArray(16); var bit = 0; for (var x = 0; x < Width - 1; x++) { for (var y = 0; y < Height; y++) { if (IsCorner(x, y, Width, Height)) { // skip corners continue; } bitArray.Set(bit, normalized[y * Height + x] < normalized[y * Height + x + 1]); bit++; } } var array = new byte[2]; bitArray.CopyTo(array, 0); return(BitConverter.ToInt16(array, 0)); }
public static double PeakSignalToNoiseRatio(Image left, Image right) { GuardImages(left, right); ImagePipeline .FromImage(left) .Raw() .ToBuffer(out var leftBuffer); ImagePipeline .FromImage(right) .Raw() .ToBuffer(out var rightBuffer); if (leftBuffer == null || rightBuffer == null) { throw new SharpSharpException("Failed to load buffers."); } double se = 0; for (var y = 0; y < left.Height; y++) { for (var x = 0; x < left.Width; x++) { for (var channel = 0; channel < left.Bands; channel++) { double e = leftBuffer[y * left.Height + x + channel] - rightBuffer[y * left.Height + x + channel]; se += e * e; } } } var mse = se / (left.Width * left.Height * left.Bands); return(10 * Math.Log10(255 * 255 / mse)); }
public static void throws_on_empty_buffer() => Should.Throw <ArgumentException>(() => ImagePipeline.FromFile(string.Empty));
public static Task throws_on_null_uri() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync((string)null, TestValues.DefaultImageLoadOptions));
public static Task throws_on_null_options() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync(TestValues.InputUrl, null));
public static async Task returns_pipeline() => (await ImagePipeline.FromUriAsync(TestValues.InputUrl, new ImageLoadOptions()).ForAwait()).ShouldNotBeNull();
public static Task throws_on_null_uri() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync((Uri)null));
public static async Task returns_pipeline() => (await ImagePipeline.FromUriAsync(TestValues.InputUrl)).ShouldNotBeNull();
public static void returns_pipeline() { using var stream = File.OpenRead(TestValues.InputPath); ImagePipeline.FromStream(stream).ShouldNotBeNull(); }
public static void returns_pipeline() => ImagePipeline.FromImage(Image).ShouldNotBeNull();
public static double StructuralSimilarity(Image left, Image right) { GuardImages(left, right); ImagePipeline .FromImage(left) .Raw() .ToBuffer(out var leftBuffer); ImagePipeline .FromImage(right) .Raw() .ToBuffer(out var rightBuffer); if (leftBuffer == null || rightBuffer == null) { throw new SharpSharpException("Failed to load buffers."); } var k1 = 0.01; var k2 = 0.03; var c1 = k1 * 255 * (k1 * 255); var c2 = k2 * 255 * (k2 * 255); var c3 = c2 / 2; double valSum1 = 0; double valSum2 = 0; for (var y = 0; y < left.Height; y++) { for (var x = 0; x < left.Width; x++) { for (var channel = 0; channel < left.Bands; channel++) { valSum1 += leftBuffer[y * left.Height + x + channel]; valSum2 += rightBuffer[y * left.Height + x + channel]; } } } var miu1 = valSum1 / (left.Width * left.Height * left.Bands); var miu2 = valSum2 / (left.Width * left.Height * left.Bands); double varSum1 = 0; double varSum2 = 0; double covSum = 0; for (var y = 0; y < left.Height; y++) { for (var x = 0; x < left.Width; x++) { for (var channel = 0; channel < left.Bands; channel++) { var e1 = leftBuffer[y * left.Height + x + channel] - miu1; var e2 = rightBuffer[y * left.Height + x + channel] - miu2; varSum1 += e1 * e1; varSum2 += e2 * e2; covSum += e1 * e2; } } } var sigma1 = Math.Sqrt(varSum1 / (left.Width * left.Height * left.Bands - 1)); var sigma2 = Math.Sqrt(varSum2 / (left.Width * left.Height * left.Bands - 1)); var sigma12 = covSum / (left.Width * left.Height * left.Bands - 1); var l = (2 * miu1 * miu2 + c1) / (miu1 * miu1 + miu2 * miu2 + c1); var c = (2 * sigma1 * sigma2 + c2) / (sigma1 * sigma1 + sigma2 * sigma2 + c2); var s = (sigma12 + c3) / (sigma1 * sigma2 + c3); return(l * c * s); }
public static void returns_pipeline() => ImagePipeline.FromFile(TestValues.InputPath).ShouldNotBeNull();
public static void throws_on_empty_buffer() => Should.Throw <ArgumentException>(() => ImagePipeline.FromBuffer(Array.Empty <byte>()));
public static void returns_pipeline() => ImagePipeline.FromBuffer(TestValues.InputBuffer).ShouldNotBeNull();