Brute-force descriptor matcher. For each descriptor in the first set, this matcher finds the closest descriptor in the second set by trying each one.
상속: DescriptorMatcher
예제 #1
1
        public void Run()
        {
            using (var img1 = new Mat(FilePath.Image.SurfBox))
            using (var img2 = new Mat(FilePath.Image.SurfBoxinscene))
            using (var descriptors1 = new Mat())
            using (var descriptors2 = new Mat())
            using (var matcher = new BFMatcher(NormTypes.L2SQR))
            using (var kaze = KAZE.Create())
            {
                KeyPoint[] keypoints1, keypoints2;
                kaze.DetectAndCompute(img1, null, out keypoints1, descriptors1);
                kaze.DetectAndCompute(img2, null, out keypoints2, descriptors2);

                DMatch[][] matches = matcher.KnnMatch(descriptors1, descriptors2, 2);
                using (Mat mask = new Mat(matches.Length, 1, MatType.CV_8U))
                {
                    mask.SetTo(new Scalar(255));
                    int nonZero = Cv2.CountNonZero(mask);
                    VoteForUniqueness(matches, mask);
                    nonZero = Cv2.CountNonZero(mask);
                    nonZero = VoteForSizeAndOrientation(keypoints2, keypoints1, matches, mask, 1.5f, 20);

                    List<Point2f> obj = new List<Point2f>();
                    List<Point2f> scene = new List<Point2f>();
                    List<DMatch> goodMatchesList = new List<DMatch>();
                    //iterate through the mask only pulling out nonzero items because they're matches
                    for (int i = 0; i < mask.Rows; i++)
                    {
                        MatIndexer<byte> maskIndexer = mask.GetGenericIndexer<byte>();
                        if (maskIndexer[i] > 0)
                        {
                            obj.Add(keypoints1[matches[i][0].QueryIdx].Pt);
                            scene.Add(keypoints2[matches[i][0].TrainIdx].Pt);
                            goodMatchesList.Add(matches[i][0]);
                        }
                    }

                    List<Point2d> objPts = obj.ConvertAll(Point2fToPoint2d);
                    List<Point2d> scenePts = scene.ConvertAll(Point2fToPoint2d);
                    if (nonZero >= 4)
                    {
                        Mat homography = Cv2.FindHomography(objPts, scenePts, HomographyMethods.Ransac, 1.5, mask);
                        nonZero = Cv2.CountNonZero(mask);

                        if (homography != null)
                        {
                            Point2f[] objCorners = { new Point2f(0, 0),
                                      new Point2f(img1.Cols, 0),
                                      new Point2f(img1.Cols, img1.Rows),
                                      new Point2f(0, img1.Rows) };

                            Point2d[] sceneCorners = MyPerspectiveTransform3(objCorners, homography);

                            //This is a good concat horizontal
                            using (Mat img3 = new Mat(Math.Max(img1.Height, img2.Height), img2.Width + img1.Width, MatType.CV_8UC3))
                            using (Mat left = new Mat(img3, new Rect(0, 0, img1.Width, img1.Height)))
                            using (Mat right = new Mat(img3, new Rect(img1.Width, 0, img2.Width, img2.Height)))
                            {
                                img1.CopyTo(left);
                                img2.CopyTo(right);

                                byte[] maskBytes = new byte[mask.Rows * mask.Cols];
                                mask.GetArray(0, 0, maskBytes);
                                Cv2.DrawMatches(img1, keypoints1, img2, keypoints2, goodMatchesList, img3, Scalar.All(-1), Scalar.All(-1), maskBytes, DrawMatchesFlags.NotDrawSinglePoints);

                                List<List<Point>> listOfListOfPoint2D = new List<List<Point>>();
                                List<Point> listOfPoint2D = new List<Point>();
                                listOfPoint2D.Add(new Point(sceneCorners[0].X + img1.Cols, sceneCorners[0].Y));
                                listOfPoint2D.Add(new Point(sceneCorners[1].X + img1.Cols, sceneCorners[1].Y));
                                listOfPoint2D.Add(new Point(sceneCorners[2].X + img1.Cols, sceneCorners[2].Y));
                                listOfPoint2D.Add(new Point(sceneCorners[3].X + img1.Cols, sceneCorners[3].Y));
                                listOfListOfPoint2D.Add(listOfPoint2D);
                                img3.Polylines(listOfListOfPoint2D, true, Scalar.LimeGreen, 2);

                                //This works too
                                //Cv2.Line(img3, scene_corners[0] + new Point2d(img1.Cols, 0), scene_corners[1] + new Point2d(img1.Cols, 0), Scalar.LimeGreen);
                                //Cv2.Line(img3, scene_corners[1] + new Point2d(img1.Cols, 0), scene_corners[2] + new Point2d(img1.Cols, 0), Scalar.LimeGreen);
                                //Cv2.Line(img3, scene_corners[2] + new Point2d(img1.Cols, 0), scene_corners[3] + new Point2d(img1.Cols, 0), Scalar.LimeGreen);
                                //Cv2.Line(img3, scene_corners[3] + new Point2d(img1.Cols, 0), scene_corners[0] + new Point2d(img1.Cols, 0), Scalar.LimeGreen);

                                img3.SaveImage("Kaze_Output.png");
                                Window.ShowImages(img3);
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        private void MatchBySurf(Mat src1, Mat src2)
        {
            var gray1 = new Mat();
            var gray2 = new Mat();

            Cv2.CvtColor(src1, gray1, ColorConversionCodes.BGR2GRAY);
            Cv2.CvtColor(src2, gray2, ColorConversionCodes.BGR2GRAY);

            var surf = SURF.Create(500, 4, 2, true);

            // Detect the keypoints and generate their descriptors using SURF
            KeyPoint[] keypoints1, keypoints2;
            var descriptors1 = new MatOfFloat();
            var descriptors2 = new MatOfFloat();
            surf.Compute(gray1, null, out keypoints1, descriptors1);
            surf.Compute(gray2, null, out keypoints2, descriptors2);

            // Match descriptor vectors 
            var bfMatcher = new BFMatcher(NormTypes.L2, false);
            var flannMatcher = new FlannBasedMatcher();
            DMatch[] bfMatches = bfMatcher.Match(descriptors1, descriptors2);
            DMatch[] flannMatches = flannMatcher.Match(descriptors1, descriptors2);

            // Draw matches
            var bfView = new Mat();
            Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, bfMatches, bfView);
            var flannView = new Mat();
            Cv2.DrawMatches(gray1, keypoints1, gray2, keypoints2, flannMatches, flannView);

            using (new Window("SURF matching (by BFMather)", WindowMode.AutoSize, bfView))
            using (new Window("SURF matching (by FlannBasedMatcher)", WindowMode.AutoSize, flannView))
            {
                Cv2.WaitKey();
            }
        }
예제 #3
-1
        private void FindMatchingFeatures_Click(object sender, EventArgs e)
        {
            var file1 = comboBox1.SelectedItem.ToString();
            var file2 = comboBox2.SelectedItem.ToString();

            using (var img1 = new Mat(file1, ImreadModes.GrayScale))
            using (var img2 = new Mat(file2, ImreadModes.GrayScale))
            using (var dst = new Mat())
            {
                // find keypoints
                //var kp1 = FindFeatures(Constants.ImageControl1);
                //var kp2 = FindFeatures(Constants.ImageControl2);

                // find descriptors
                var descriptors1 = new Mat();
                var descriptors2 = new Mat();

                var kp1 = FindFeaturesDescriptors_ORB(file1, out descriptors1);
                var kp2 = FindFeaturesDescriptors_ORB(file2, out descriptors2);

                // find keypoint matches
                var bfMatcher = new BFMatcher(NormTypes.Hamming2, true);
                DMatch[] bfMatches = bfMatcher.Match(descriptors1, descriptors2);

                // draw things
                Cv2.DrawMatches(img1, kp1, img2, kp2, bfMatches, dst);
                using (new Window("ORB matching (by BFMatcher)", WindowMode.FreeRatio, dst))
                {
                    Cv2.WaitKey();
                }
            }
        }