Maximum cross-correlation feature point matching algorithm.

This class matches feature points by using a maximum cross-correlation measure.

References: P. D. Kovesi. MATLAB and Octave Functions for Computer Vision and Image Processing. School of Computer Science and Software Engineering, The University of Western Australia. Available in: http://www.csse.uwa.edu.au/~pk/Research/MatlabFns/Match/matchbycorrelation.m http://www.instructor.com.br/unesp2006/premiados/PauloHenrique.pdf http://siddhantahuja.wordpress.com/2010/04/11/correlation-based-similarity-measures-summary/

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

            // 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)));

            pictureBox.Image = pairs.Apply(img3);
        }
        /// <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 = 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)
                },

            };

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

            Assert.IsTrue(actual.IsEqual(expected));
        }
Exemplo n.º 4
0
        private void BtnCorrelation_OnClick(object sender, RoutedEventArgs e)
        {
            // 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)));

            PictureBox.Source = pairs.Apply(img3);
        }
Exemplo n.º 5
0
        public void MatchTest2()
        {
            for (int windowSize = 1; windowSize <= 15; windowSize += 2)
            {
                CorrelationMatching target = new CorrelationMatching(windowSize);
                Bitmap image1 = Properties.Resources.image1;
                Bitmap image2 = 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
                IntPoint[][] actual = target.Match(image1, image2, points.ToArray(), points.ToArray());

                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);
                }

            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Matches detected keypoints.
        /// </summary>
        private void MatchKeypoints()
        {
            // matching keypoints step needs at least two images
            if (input_images.Count < 2) return;

            // using RANSAC homography estimator
            RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);
            CorrelationMatching matcher = new CorrelationMatching(9);

            Bitmap mergedImage = new Bitmap(input_images.Count * input_images[0].Width, input_images[0].Height); //it is assumed the images are of same size!
            Graphics graphics = Graphics.FromImage(mergedImage);

            IntPoint[][] matches;

            int cumulativeWidth = 0;
            int keypoints_cntr = 0;

            // draw all images
            for (int i = 0; i < input_images.Count; i++) {
                graphics.DrawImage(input_images[i], cumulativeWidth, 0, input_images[i].Width, input_images[i].Height);
                cumulativeWidth += input_images[i].Width;
            }

            // iterate through all images
            for (int i = 0; i < input_images.Count; i++)
            {

                if (i != input_images.Count - 1)
                {
                    // match detected keypoints with maximum cross-correlation algorithm
                    matches = matcher.Match(new Bitmap(input_images[i]), new Bitmap(input_images[i + 1]), keypoints[keypoints_cntr].ToArray(), keypoints[keypoints_cntr + 1].ToArray());

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

                    // Plot RANSAC results against correlation results
                    homography = ransac.Estimate(correlationPoints1, correlationPoints2);

                    // take only inliers - good matches
                    IntPoint[] inliers1 = correlationPoints1.Submatrix(ransac.Inliers);
                    IntPoint[] inliers2 = correlationPoints2.Submatrix(ransac.Inliers);

                    PairsMarker pairs = new PairsMarker(correlationPoints1, correlationPoints2.Apply(p => new IntPoint(p.X + input_images[i].Width, p.Y)));

                    // draw all matching pairs
                    for (int j = 0; j < pairs.Points1.Count(); j++) {
                        if (i % 2 == 0) graphics.DrawLine(new Pen(Color.Red, 1.5f), new System.Drawing.Point(correlationPoints1[j].X + i * input_images[i].Width, correlationPoints1[j].Y), new System.Drawing.Point(correlationPoints2[j].X + (i + 1) * input_images[i].Width, correlationPoints2[j].Y));
                    }

                    // draw inliers
                    for (int j = 0; j < inliers1.Count(); j++) {
                        if (i % 2 == 0) graphics.DrawLine(new Pen(Color.GreenYellow, 1.5f), new System.Drawing.Point(inliers1[j].X + i * input_images[i].Width, inliers1[j].Y), new System.Drawing.Point(inliers2[j].X + (i + 1) * input_images[i].Width, inliers2[j].Y));
                        else            graphics.DrawLine(new Pen(Color.Blue, 1.5f), new System.Drawing.Point(inliers1[j].X + i * input_images[i].Width, inliers1[j].Y), new System.Drawing.Point(inliers2[j].X + (i + 1) * input_images[i].Width, inliers2[j].Y));
                    }

                    keypoints_cntr += 2;
                }
            }

            ShowThumbnail(mergedImage, true, PanoramaPhase.MatchKeypoints);
        }
Exemplo n.º 7
0
        private bool GenerateKeypointMatches(Bitmap target, Bitmap frame, Rectangle prevTarget)
        {
            HarrisCornersDetector harrisDetector = new HarrisCornersDetector(HarrisCornerMeasure.Harris, 1000f, 1f, 2);
            targetKeyPoints=harrisDetector.ProcessImage(target).ToArray();
            frameKeyPoints=harrisDetector.ProcessImage(frame).ToArray();
            //Console.WriteLine("tr={0} fr={1}", targetKeyPoints.Length, frameKeyPoints.Length);
            if (targetKeyPoints.Length==0||frameKeyPoints.Length==0)
            {
                return false;
            }

            CorrelationMatching matcher=new CorrelationMatching(15);
            IntPoint[][] matches=matcher.Match(target, frame, targetKeyPoints, frameKeyPoints);
            targetMacthes=matches[0];
            frameMatches=matches[1];
            if (targetMacthes.Length<4||frameMatches.Length<4)
            {
                return false;
            }
            RansacHomographyEstimator ransac=new RansacHomographyEstimator(0.1, 0.50);
            MatrixH estiment = new MatrixH();
            try
            {

                estiment = ransac.Estimate(targetMacthes, frameMatches);
            }
            catch
            {
                return false;
            }
            IntPoint[] targetGoodMatch=targetMacthes.Submatrix(ransac.Inliers);
            IntPoint[] frameGoodMatch=frameMatches.Submatrix(ransac.Inliers);
            CalculatePosChange(targetGoodMatch, frameGoodMatch, prevTarget);
            return true;
        }
Exemplo n.º 8
0
        // PANORAMIC STICHING CODE
        // Accord.NET and AForge.NET frameworks and code examples provided from
        // http://www.codeproject.com/KB/recipes/automatic_panoramas.aspx
        private void panoramicStitchingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Save a copy of the current image, ask user to open another image to merge with
            Bitmap img2 = img;
            openToolStripMenuItem_Click(sender, e);

            // Check whether the current loaded image is different
            // (If the user cancelled the open image operation, the current image in the viewer
            // is still the same image object)
            if (img2 != img)
            {
                Bitmap img1 = img;

                AForge.IntPoint[] harrisPoints1;
                AForge.IntPoint[] harrisPoints2;

                AForge.IntPoint[] correlationPoints1;
                AForge.IntPoint[] correlationPoints2;

                MatrixH homography;

                // Use Harris Corners Detector to find points of interest
                HarrisCornersDetector harris = new HarrisCornersDetector(0.04f, 1000f);
                harrisPoints1 = harris.ProcessImage(img1).ToArray();
                harrisPoints2 = harris.ProcessImage(img2).ToArray();

                // This check fixes an out of bounds exception generated by matcher.Match() below when a
                // monocolour image (0 harris points) is stitched with a non-monocolour image
                if (harrisPoints1.Length == 0 || harrisPoints2.Length == 0)
                {
                    MessageBox.Show("Panoramic stitching cannot continue because at least one of the images does not contain any Harris points.", "Warning");
                }
                else
                {
                    // Match detected points using correlation
                    CorrelationMatching matcher = new CorrelationMatching(9);
                    AForge.IntPoint[][] matches = matcher.Match(img1, img2, harrisPoints1, harrisPoints2);

                    // Separate the two arrays
                    correlationPoints1 = matches[0];
                    correlationPoints2 = matches[1];

                    // Find homography matrix using RANSAC algorithm
                    RansacHomographyEstimator ransac = new RansacHomographyEstimator(0.001, 0.99);

                    // This check is to handle the ransac.Estimate() function
                    // which throws an exception if the array parameters do not contain at least 4 elements
                    if (correlationPoints1.Length < 4 || correlationPoints2.Length < 4)
                    {
                        MessageBox.Show("Panoramic stitching cannot continue because at least one of the images does not contain at least 4 correlation points.", "Warning");
                    }
                    else
                    {
                        homography = ransac.Estimate(correlationPoints1, correlationPoints2);

                        // Merge the images
                        Blend blend = new Blend(homography, img1);
                        img = blend.Apply(img2);

                        //save the image properly and resize main form
                        origImg.Dispose();
                        origImg = new Bitmap(img);
                        pictureBox.Image = img;
                        mainForm.ActiveForm.Width = img.Width + widthPad;
                        mainForm.ActiveForm.Height = img.Height + heightPad;
                    }
                }
            }
        }