//Relies less on neighbor pixels and more on RANSAC
    protected void fastHarrisRansacBlend(List <Bitmap> imgs)
    {
        List <IntPoint[]> harrisPoints = new List <IntPoint[]>();
        MatrixH           homography;

        //Calculate all the Harris Points
        HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f);

        for (int i = 0; i < imgs.Count; i++)
        {
            harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray());
        }

        Bitmap final = imgs[0];

        for (int i = 1; i < imgs.Count; i++)
        {
            IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray();

            //Correlate the Harris pts between imgs
            CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]);
            IntPoint[][]        matches = matcher.Match(harrisFinal, harrisPoints[i]);

            //Create the homography matrix using ransac
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99);
            homography = ransac.Estimate(matches[0], matches[1]);

            Blend blend = new Blend(homography, final);
            blend.Gradient = true;
            final          = blend.Apply(imgs[i]);
        }

        showImage(final);
    }
Esempio n. 2
0
        private void btnCorrelation_Click(object sender, EventArgs e)
        {
            if (harrisPoints1 == null)
            {
                MessageBox.Show("Please click the Harris button first! :-)");
                return;
            }

            // Step 2: Match feature points using a correlation measure
            CorrelationMatching matcher = new CorrelationMatching(9, img1, img2);

            IntPoint[][] matches = matcher.Match(harrisPoints1, harrisPoints2);

            // Get the two sets of points
            correlationPoints1 = matches[0];
            correlationPoints2 = matches[1];

            // Concatenate the two images in a single image (just to show on screen)
            Concatenate concat = new Concatenate(img1);
            Bitmap      img3   = concat.Apply(img2);

            // Show the marked correlations in the concatenated image
            PairsMarker pairs = new PairsMarker(
                correlationPoints1, // Add image1's width to the X points to show the markings correctly
                correlationPoints2.Apply(p => new IntPoint(p.X + img1.Width, p.Y)));

            pictureBox.Image = pairs.Apply(img3);
        }
Esempio n. 3
0
        /*
         * Matches feature points using a correlation measure.
         */
        private void CorrelationMatchingRecursive()
        {
            CorrelationMatching matcher = new CorrelationMatching(9);

            IntPoint[][] matches = matcher.Match(images[0], images[1], harrisPoints1, harrisPoints2);
            // Get the two sets of points
            correlationPoints1 = matches[0];
            correlationPoints2 = matches[1];
        }
        public void MatchTest2()
        {
            for (int windowSize = 1; windowSize <= 15; windowSize += 2)
            {
#pragma warning disable 0618
                CorrelationMatching target = new CorrelationMatching(windowSize);
#pragma warning restore 0618

                Bitmap image1 = Accord.Imaging.Image.Clone(Properties.Resources.image1);
                Bitmap image2 = Accord.Imaging.Image.Clone(Properties.Resources.image1);

                Assert.AreEqual(16, image1.Height);
                Assert.AreEqual(16, image2.Height);

                Assert.AreEqual(16, image1.Width);
                Assert.AreEqual(16, image2.Width);

                // will test every possible point in the image
                // (and also some points outside just to make sure)
                List <IntPoint> points = new List <IntPoint>();
                for (int i = -5; i < 20; i++)
                {
                    for (int j = -5; j < 20; j++)
                    {
                        points.Add(new IntPoint(i, j));
                    }
                }


                // Assert that no exception if thrown
#pragma warning disable 0618
                IntPoint[][] actual = target.Match(image1, image2, points.ToArray(), points.ToArray());
#pragma warning restore 0618

                Assert.IsNotNull(actual);
                Assert.AreEqual(2, actual.Length);

                var p1 = actual[0]; var p2 = actual[1];
                Assert.AreEqual(p1.Length, p2.Length);


                for (int i = 0; i < p1.Length; i++)
                {
                    // As the images are the same, assert that
                    // each point correlates with itself.
                    Assert.AreEqual(p1[i], p2[i]);

                    // Also assert we have no bogus values
                    Assert.IsTrue(p1[i].X >= 0 && p1[i].X < 16);
                    Assert.IsTrue(p1[i].Y >= 0 && p1[i].Y < 16);
                }
            }
        }
    protected void fastHarrisRansacBlendStraight(List <Bitmap> imgs)
    {
        List <IntPoint[]> harrisPoints = new List <IntPoint[]>();
        MatrixH           homography;

        //Calculate all the Harris Points
        HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f);

        for (int i = 0; i < imgs.Count; i++)
        {
            harrisPoints.Add(harris.ProcessImage(imgs[i]).ToArray());
        }

        Bitmap final = imgs[0];

        for (int i = 1; i < imgs.Count; i++)
        {
            //Convert my frames to grayscale so I can find and adjust the normal vectors
            AForge.Imaging.Filters.GrayscaleBT709 grayscale = new AForge.Imaging.Filters.GrayscaleBT709();
            AForge.Imaging.DocumentSkewChecker    skew      = new AForge.Imaging.DocumentSkewChecker();

            double finalAngle = skew.GetSkewAngle(grayscale.Apply(final));
            double imgAngle   = skew.GetSkewAngle(grayscale.Apply(imgs[i]));

            //Less than 5% to account for human error with rotations and wobbles
            if (Math.Abs(finalAngle - imgAngle) < 5)
            {
                AForge.Imaging.Filters.RotateBilinear rotate = new AForge.Imaging.Filters.RotateBilinear(finalAngle - imgAngle);
                rotate.FillColor = Color.FromArgb(0, 255, 255, 255);
                imgs[i]          = rotate.Apply(imgs[i]);

                //Update harris
                harrisPoints[i] = harris.ProcessImage(imgs[i]).ToArray();
            }

            IntPoint[] harrisFinal = harris.ProcessImage(final).ToArray();

            //Correlate the Harris pts between imgs
            CorrelationMatching matcher = new CorrelationMatching(5, final, imgs[i]);
            IntPoint[][]        matches = matcher.Match(harrisFinal, harrisPoints[i]);

            //Create the homography matrix using ransac
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99);
            homography = ransac.Estimate(matches[0], matches[1]);

            Blend blend = new Blend(homography, final);
            blend.Gradient = true;
            final          = blend.Apply(imgs[i]);
        }

        showImage(final);
    }
        /// <summary>
        ///  Maximum cross-correlation feature point matching algorithm.
        /// </summary>
        /// <param name="correlationMatching"> Maximum cross-correlation feature point matching algorithm.</param>
        /// <param name="image1">First image.</param>
        /// <param name="image2">Second image.</param>
        /// <param name="points1">Points from the first image.</param>
        /// <param name="points2">Points from the second image.</param>
        /// <returns>Matched point-pairs.</returns>
        public static Point[][] Match(this CorrelationMatching correlationMatching,
                                      Image <Gray, byte> image1, Image <Gray, byte> image2, Point[] points1, Point[] points2)
        {
            var result = correlationMatching.Match
                         (
                image1.ToBitmap(copyAlways: false, failIfCannotCast: true),
                image2.ToBitmap(copyAlways: false, failIfCannotCast: true),
                points1,
                points2
                         );

            return(result);
        }
Esempio n. 7
0
        /// <summary>
        ///  Maximum cross-correlation feature point matching algorithm.
        /// </summary>
        /// <param name="image1">First image.</param>
        /// <param name="image2">Second image.</param>
        /// <param name="points1">Points from the first image.</param>
        /// <param name="points2">Points from the second image.</param>
        /// <param name="windowSize">The size of the correlation window.</param>
        /// <param name="maxDistance">The maximum distance to consider points as correlated.</param>
        /// <returns>Matched point-pairs.</returns>
        public static Point[][] Match(Gray <byte>[,] image1, Gray <byte>[,] image2, Point[] points1, Point[] points2, int windowSize, int maxDistance)
        {
            Point[][] matches = null;

            using (var uImg1 = image1.Lock())
                using (var uImg2 = image2.Lock())
                {
                    var correlationMatching = new CorrelationMatching(windowSize, maxDistance, uImg1.AsBitmap(), uImg2.AsBitmap());
                    matches = correlationMatching.Match(points1.ToPoints(), points2.ToPoints()).ToPoints();
                }

            return(matches);
        }
        public void MatchTest()
        {
            int windowSize = 3;

#pragma warning disable 0618
            CorrelationMatching target = new CorrelationMatching(windowSize);
#pragma warning restore 0618
            Bitmap image1 = Accord.Imaging.Image.Clone(Properties.Resources.image1);
            Bitmap image2 = Accord.Imaging.Image.Clone(Properties.Resources.image1);

            IntPoint[] points1 =
            {
                new IntPoint(3,   3),
                new IntPoint(14,  3),
                new IntPoint(3,  14),
                new IntPoint(14, 14),
            };

            IntPoint[] points2 =
            {
                new IntPoint(3,   3),
                new IntPoint(14,  3),
                new IntPoint(3,  14),
                new IntPoint(14, 14),
            };

            IntPoint[][] expected =
            {
                new IntPoint[]
                {
                    new IntPoint(3, 3),
                    new IntPoint(14, 3),
                    new IntPoint(3, 14),
                    new IntPoint(14, 14)
                },

                new IntPoint[]
                {
                    new IntPoint(3, 3),
                    new IntPoint(14, 3),
                    new IntPoint(3, 14),
                    new IntPoint(14, 14)
                },
            };

#pragma warning disable 0618
            IntPoint[][] actual = target.Match(image1, image2, points1, points2);
#pragma warning restore 0618

            Assert.IsTrue(actual.IsEqual(expected));
        }
Esempio n. 9
0
        public void MatchTest()
        {
            int windowSize             = 3;
            CorrelationMatching target = new CorrelationMatching(windowSize);
            Bitmap image1 = Properties.Resources.image1;
            Bitmap image2 = Properties.Resources.image1;

            IntPoint[] points1 =
            {
                new IntPoint(3,   3),
                new IntPoint(14,  3),
                new IntPoint(3,  14),
                new IntPoint(14, 14),
            };

            IntPoint[] points2 =
            {
                new IntPoint(3,   3),
                new IntPoint(14,  3),
                new IntPoint(3,  14),
                new IntPoint(14, 14),
            };

            IntPoint[][] expected =
            {
                new IntPoint[]
                {
                    new IntPoint(3, 3),
                    new IntPoint(14, 3),
                    new IntPoint(3, 14),
                    new IntPoint(14, 14)
                },

                new IntPoint[]
                {
                    new IntPoint(3, 3),
                    new IntPoint(14, 3),
                    new IntPoint(3, 14),
                    new IntPoint(14, 14)
                },
            };

            IntPoint[][] actual = target.Match(image1, image2, points1, points2);

            Assert.IsTrue(actual.IsEqual(expected));
        }
Esempio n. 10
0
        public Task <MatrixH> Adjust(Bitmap baseBitmap, Size baseOriginalSize, Bitmap targetBitmap, Size targetOriginalSize)
        {
            return(Task.Run(() =>
            {
                var basePoints = keypointDetector.Transform(baseBitmap).Select(p => new IntPoint((int)Math.Round(p.X), (int)Math.Round(p.Y))).ToArray();
                var targetPoints = keypointDetector.Transform(targetBitmap).Select(p => new IntPoint((int)Math.Round(p.X), (int)Math.Round(p.Y))).ToArray();

                var matches = new CorrelationMatching(9, 50, baseBitmap, targetBitmap).Match(basePoints, targetPoints);

                var baseMatchPoints = matches[0].Select(p => new IntPoint(p.X * baseOriginalSize.Width / baseBitmap.Width, p.Y * baseOriginalSize.Height / baseBitmap.Height)).ToArray();
                var targetMatchPoints = matches[1].Select(p => new IntPoint(p.X * targetOriginalSize.Width / targetBitmap.Width, p.Y * targetOriginalSize.Height / targetBitmap.Height)).ToArray();

                var tasks = Enumerable.Range(0, 20).AsParallel().Select(a =>
                {
                    RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
                    ransac.Ransac.MaxEvaluations = 1000;
                    ransac.Ransac.MaxSamplings = 100;

                    var homography = ransac.Estimate(baseMatchPoints, targetMatchPoints);

                    if (ransac.Inliers.Length > 0)
                    {
                        var directions =
                            Accord.Math.Matrix.Get(baseMatchPoints, ransac.Inliers).Zip(
                                Accord.Math.Matrix.Get(targetMatchPoints, ransac.Inliers),
                                (point1, point2) => Math.Atan2(point2.Y - point1.Y, point2.X - point1.X) + Math.PI * 2).ToArray();

                        var avgDirection = directions.Average();
                        var variance = directions.Average(d => Math.Pow(d - avgDirection, 2));

                        return new
                        {
                            homography,
                            ransac.Inliers.Length,
                            variance
                        };
                    }
                    else
                    {
                        return null;
                    }
                }).Where(h => h != null).OrderByDescending(h => h.Length).ThenBy(h => h.variance).ToArray();

                return tasks.FirstOrDefault()?.homography;
            }));
        }
    protected void drawFastHarrisFeaturesCorrelations(List <Bitmap> imgs)
    {
        List <IntPoint[]> harrisPoints = new List <IntPoint[]>();
        MatrixH           homography;
        //Calculate all the Harris Points
        HarrisCornersDetector harris = new HarrisCornersDetector(0.03f, 10000f);

        foreach (Bitmap img in imgs)
        {
            harrisPoints.Add(harris.ProcessImage(img).ToArray());
        }

        //Map them and draw them!
        Bitmap harrisImg = imgs[0];

        for (int i = 0; i < imgs.Count - 1; i++)
        {
            //Correlate the Harris pts between imgs
            CorrelationMatching matcher = new CorrelationMatching(5, imgs[i], imgs[i + 1]);
            IntPoint[][]        matches = matcher.Match(harrisPoints[i], harrisPoints[i + 1]);

            //Create the homography matrix using ransac
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.025, 0.99);
            homography = ransac.Estimate(matches[0], matches[1]);

            Concatenate concat = new Concatenate(harrisImg);
            Bitmap      img    = concat.Apply(imgs[i + 1]);

            Color color = Color.White;
            if (i % 3 == 1)
            {
                color = Color.OrangeRed;
            }
            if (i % 3 == 2)
            {
                color = Color.Blue;
            }
            PairsMarker pairs = new PairsMarker(matches[0].Apply(p => new IntPoint(p.X + harrisImg.Width - imgs[0].Width, p.Y)), matches[1].Apply(p => new IntPoint(p.X + harrisImg.Width, p.Y)), color);
            harrisImg = pairs.Apply(img);
        }

        showImage(harrisImg);
    }
Esempio n. 12
0
        /// <summary>
        /// </summary>
        /// <param name="sender">
        /// </param>
        /// <param name="e">
        /// </param>
        private void BtnCorrelation_OnClick(object sender, RoutedEventArgs e)
        {
            // Step 2: Match feature points using a correlation measure
            var matcher = new CorrelationMatching(9, this.img1, this.img2);
            var matches = matcher.Match(this.harrisPoints1, this.harrisPoints2);

            // Get the two sets of points
            this.correlationPoints1 = matches[0];
            this.correlationPoints2 = matches[1];

            // Concatenate the two images in a single image (just to show on screen)
            var concat = new Concatenate(this.img1);
            var img3   = concat.Apply(this.img2);

            // Show the marked correlations in the concatenated image
            var pairs = new PairsMarker(this.correlationPoints1, // Add image1's width to the X points to show the markings correctly
                                        this.correlationPoints2.Apply(p => new IntPoint(p.X + this.img1.Width, p.Y)));

            this.PictureBox.Source = (ImageSource)pairs.Apply(img3);
        }
Esempio n. 13
0
        // Correlation Matching
        private void Correlator()
        {
            // Step 2: Match feature points using a correlation measure
            CorrelationMatching matcher = new CorrelationMatching(9);

            IntPoint[][] matches = matcher.Match(_img1, _img2, harrisPoints1, harrisPoints2);

            // Get the two sets of points
            correlationPoints1 = matches[0];
            correlationPoints2 = matches[1];

            // Concatenate the two images in a single image (just to show on screen)
            Concatenate concat = new Concatenate(_img1);
            Bitmap      img3   = concat.Apply(_img2);

            // Show the marked correlations in the concatenated image
            PairsMarker pairs = new PairsMarker(
                correlationPoints1, // Add image1's width to the X points
                                    // to show the markings correctly
                correlationPoints2.Apply(p => new IntPoint(p.X + _img1.Width, p.Y)));

            _processImage2 = pairs.Apply(img3);
        }
Esempio n. 14
0
        public static Geometry AutoAlign(Bitmap needle, Bitmap haystack, double retryThreshold = 1, int retryLimit = 10)
        {
            IntPoint[] harrisPoints1;
            IntPoint[] harrisPoints2;
            IntPoint[] correlationPoints1;
            IntPoint[] correlationPoints2;
            MatrixH    homography;

            var mi1 = new MagickImage(needle); mi1.Equalize(); needle = mi1.ToBitmap();
            var mi2 = new MagickImage(haystack); mi2.Equalize(); haystack = mi2.ToBitmap();

            HarrisCornersDetector harris = new HarrisCornersDetector(0.04f, 20000f);

            harrisPoints1 = harris.ProcessImage(needle).ToArray();
            harrisPoints2 = harris.ProcessImage(haystack).ToArray();

            CorrelationMatching matcher = new CorrelationMatching(9, needle, haystack);

            IntPoint[][] matches = matcher.Match(harrisPoints1, harrisPoints2);

            correlationPoints1 = matches[0];
            correlationPoints2 = matches[1];

            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.999);

            homography = ransac.Estimate(correlationPoints1, correlationPoints2);

            IntPoint[] inliers1 = correlationPoints1.Get(ransac.Inliers);
            IntPoint[] inliers2 = correlationPoints2.Get(ransac.Inliers);

            Concatenate concat = new Concatenate(needle);
            Bitmap      img3   = concat.Apply(haystack);

            PairsMarker pairs = new PairsMarker(
                inliers1,
                inliers2.Apply(p => new IntPoint(p.X + needle.Width, p.Y)));

            var Image = pairs.Apply(img3);

            Image.Save(@"C:\AutoAlignDebug.png");

            var pointCount = inliers1.Length;

            int[] xList1 = new int[pointCount];
            int[] yList1 = new int[pointCount];
            int[] xList2 = new int[pointCount];
            int[] yList2 = new int[pointCount];

            for (int n = 0; n < pointCount; n++)
            {
                xList1[n] = inliers1[n].X;
                yList1[n] = inliers1[n].Y;
                xList2[n] = inliers2[n].X;
                yList2[n] = inliers2[n].Y;
            }

            var f = new double[8] {
                xList1.Min(), yList1.Min(), xList1.Max(), yList1.Max(), xList2.Min(), yList2.Min(), xList2.Max(), yList2.Max()
            };

            double distFromX1  = f[0] / needle.Width;
            double distFromX2  = f[2] / needle.Width;
            double leftRatio   = f[0] / (f[2] - f[0]);
            double rightRatio  = (needle.Width - f[2]) / (f[2] - f[0]);
            double distFromY1  = f[1] / needle.Height;
            double distFromY2  = f[3] / needle.Height;
            double topRatio    = f[1] / (f[3] - f[1]);
            double bottomRatio = (needle.Height - f[3]) / (f[3] - f[1]);

            double leftDist   = (f[6] - f[4]) * leftRatio;
            double rightDist  = (f[6] - f[4]) * rightRatio;
            double topDist    = (f[7] - f[5]) * topRatio;
            double bottomDist = (f[7] - f[5]) * bottomRatio;

            double x      = f[4] - leftDist;
            double y      = f[5] - topDist;
            double width  = leftDist + (f[6] - f[4]) + rightDist;
            double height = topDist + (f[7] - f[5]) + bottomDist;

            mi1.Resize(new MagickGeometry((int)Math.Round(width), (int)Math.Round(height))
            {
                IgnoreAspectRatio = true
            });
            var mg = new MagickGeometry((int)Math.Round(x), (int)Math.Round(y), (int)Math.Round(width), (int)Math.Round(height))
            {
                IgnoreAspectRatio = true
            };

            mi2.Extent(mg, Gravity.Northwest, MagickColor.FromRgba(0, 0, 0, 0));

            double delta = mi1.Compare(mi2, ErrorMetric.NormalizedCrossCorrelation);

            Geometry outGeo = new Geometry(x, y, width, height);

            if (delta < retryThreshold && retryLimit > 0)
            {
                retryLimit--;
                outGeo = AutoAlign(needle, haystack, delta, retryLimit);
            }

            return(outGeo);
        }