OpenCV过滤ORB匹配 [英] OpenCV filtering ORB matches

查看:113
本文介绍了OpenCV过滤ORB匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用ORB功能检测器使用此代码查找两个图像之间的匹配:

I am using the ORB feature detector to find matches between two images using this code:

    FeatureDetector detector = FeatureDetector.create(FeatureDetector.ORB);
    DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);;
    DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

    // First photo
    Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
    Mat descriptors1 = new Mat();
    MatOfKeyPoint keypoints1 = new MatOfKeyPoint();

    detector.detect(img1, keypoints1);
    descriptor.compute(img1, keypoints1, descriptors1);

    // Second photo
    Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGB2GRAY);
    Mat descriptors2 = new Mat();
    MatOfKeyPoint keypoints2 = new MatOfKeyPoint();

    detector.detect(img2, keypoints2);
    descriptor.compute(img2, keypoints2, descriptors2);

    // Matching

    MatOfDMatch matches = new MatOfDMatch();
    MatOfDMatch filteredMatches = new MatOfDMatch();
    matcher.match(descriptors1, descriptors2, matches);

    // Linking
    Scalar RED = new Scalar(255,0,0);
    Scalar GREEN = new Scalar(0,255,0);

    List<DMatch> matchesList = matches.toList();
    Double max_dist = 0.0;
    Double min_dist = 100.0;

    for(int i = 0;i < matchesList.size(); i++){
        Double dist = (double) matchesList.get(i).distance;
        if (dist < min_dist)
            min_dist = dist;
        if ( dist > max_dist)
            max_dist = dist;
    }



    LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
    for(int i = 0;i < matchesList.size(); i++){
        if (matchesList.get(i).distance <= (1.5 * min_dist))
            good_matches.addLast(matchesList.get(i));
    }



    // Printing
    MatOfDMatch goodMatches = new MatOfDMatch();
    goodMatches.fromList(good_matches);

    System.out.println(matches.size() + " " + goodMatches.size());

    Mat outputImg = new Mat();
    MatOfByte drawnMatches = new MatOfByte();
    Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, outputImg, GREEN, RED, drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

    Highgui.imwrite("matches.png", outputImg);

我的问题是我找不到过滤匹配的方法,以便它们只匹配时他们在照片中有类似的位置。我总是得到一个关键点的多个匹配,即使它们位置非常远。

My problem is that I can't find a way to filter the matches so that they only match when they have similar positions in the photos. I always get multiple matches for one keypoint even if they are very far away position-wise.

有没有办法更好地过滤它们?

Is there a way to filter them better?

推荐答案

为了获得更好的匹配结果,您应该按照给定的顺序包含这些过滤方法。

To get better matching results you should include these filtering methods in the given order.


  1. 在两个方向上进行匹配,即第一张图片中的每个点
    在第二张图片中找到最佳匹配,反之亦然。

  1. Perform matching in two directions i.e for each point in first image find the best match in second image and vice versa .


匹配之间执行比率测试(欧几里德距离的比率测试)以消除模糊匹配。

Perform ratio test(ratio test of euclidean distances) between matches to eliminate ambiguous matches .

您可以在计算机视觉应用程序编程手册的第9章中获得上述方法的所有细节。它还有用于实现这些过滤技术的示例代码。这很容易理解。
(注意:本书中的代码是用C ++编写的,但是一旦理解,它也可以在JAVA中轻松实现)

You can get all the details of above methods in chapter 9 of Computer vision application programming cookbook. It also has sample code for implementing these filtering techniques. It is very easy to understand. (Note: The code in this book is in C++ but once you understand, it can be easily implemented in JAVA too)

这篇关于OpenCV过滤ORB匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆