コード例 #1
0
        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));
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
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));
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
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));
        }
コード例 #6
0
 public static void throws_on_empty_buffer() => Should.Throw <ArgumentException>(() => ImagePipeline.FromFile(string.Empty));
コード例 #7
0
 public static Task throws_on_null_uri() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync((string)null, TestValues.DefaultImageLoadOptions));
コード例 #8
0
 public static Task throws_on_null_options() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync(TestValues.InputUrl, null));
コード例 #9
0
 public static async Task returns_pipeline() => (await ImagePipeline.FromUriAsync(TestValues.InputUrl, new ImageLoadOptions()).ForAwait()).ShouldNotBeNull();
コード例 #10
0
 public static Task throws_on_null_uri() => Should.ThrowAsync <ArgumentNullException>(() => ImagePipeline.FromUriAsync((Uri)null));
コード例 #11
0
 public static async Task returns_pipeline() => (await ImagePipeline.FromUriAsync(TestValues.InputUrl)).ShouldNotBeNull();
コード例 #12
0
 public static void returns_pipeline()
 {
     using var stream = File.OpenRead(TestValues.InputPath);
     ImagePipeline.FromStream(stream).ShouldNotBeNull();
 }
コード例 #13
0
 public static void returns_pipeline() => ImagePipeline.FromImage(Image).ShouldNotBeNull();
コード例 #14
0
        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);
        }
コード例 #15
0
 public static void returns_pipeline() => ImagePipeline.FromFile(TestValues.InputPath).ShouldNotBeNull();
コード例 #16
0
 public static void throws_on_empty_buffer() => Should.Throw <ArgumentException>(() => ImagePipeline.FromBuffer(Array.Empty <byte>()));
コード例 #17
0
 public static void returns_pipeline() => ImagePipeline.FromBuffer(TestValues.InputBuffer).ShouldNotBeNull();