两幅图像的特征匹配匹配率

时间:2015-01-04 08:00:04

标签: android opencv feature-detection

我正在创建一个应用程序,它将输入图像与数据库中的图像相匹配。

我仍然使用此代码:

   String path = Environment.getExternalStorageDirectory().getAbsolutePath();  

   Bitmap objectbmp = BitmapFactory.decodeFile(path+"/Sample/Template.jpg");
   Bitmap scenebmp = BitmapFactory.decodeFile(path+"/Sample/Input.jpg");

    Mat object = new Mat(); //from the database
    Mat scene = new Mat(); //user's input image

    // convert bitmap to MAT
    Utils.bitmapToMat(objectbmp, object);
    Utils.bitmapToMat(scenebmp, scene);

    //Feature Detection
    FeatureDetector orbDetector = FeatureDetector.create(FeatureDetector.ORB);
    DescriptorExtractor orbextractor = DescriptorExtractor.create(DescriptorExtractor.ORB);

    MatOfKeyPoint keypoints_object = new MatOfKeyPoint();
    MatOfKeyPoint keypoints_scene = new MatOfKeyPoint();

    Mat descriptors_object = new Mat();
    Mat descriptors_scene = new Mat();

    //Getting the keypoints
    orbDetector.detect( object, keypoints_object );
    orbDetector.detect( scene, keypoints_scene );

    //Compute descriptors
    orbextractor.compute( object, keypoints_object, descriptors_object );
    orbextractor.compute( scene, keypoints_scene, descriptors_scene );

    //Match with Brute Force
    MatOfDMatch matches = new MatOfDMatch();
    DescriptorMatcher matcher;
    matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);
    matcher.match( descriptors_object, descriptors_scene, matches );

    double max_dist = 0;
    double min_dist = 100;

    List<DMatch> matchesList = matches.toList();

    //-- Quick calculation of max and min distances between keypoints
      for( int i = 0; i < descriptors_object.rows(); i++ )
      { double dist = 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 < descriptors_object.rows(); i++ )
      { if( matchesList.get(i).distance <= 3*min_dist ) 
         { good_matches.addLast( matchesList.get(i));
        }
      }

我能够制作和计算好的比赛,我想要的是知道两个匹配的图像之间的匹配率,如:

输入 - Template1 = 35% 输入 - Template2 = 12% .....................

怎么做?

1 个答案:

答案 0 :(得分:1)

您可以像goodMatches / totMatches一样计算匹配率,即匹配的准确性。

实际上有不同的方法可以做到这一点。常见的是:

  • 交叉检查:如果T1与T2匹配,请检查T2是否检查T1
  • 比率检查:与在SIFT中一样,如果与T1匹配的最佳模板为T2,则考虑第二个最佳匹配模板T2_2,并且仅当匹配之间的比率足够好时才接受第一个匹配。
  • 几何验证:您应该计算模板之间的单应性并丢弃不同意的匹配

我在Android应用程序中实现了Java中的前两个(我使用ORB作为功能)。

private List<MatOfDMatch> crossCheck(List<DMatch> matches12, List<DMatch> matches21, List<MatOfDMatch> knn_matches) {

    List<MatOfDMatch> good_matches = new ArrayList<MatOfDMatch>();

    for(int i=0; i<matches12.size(); i++)
    {
        DMatch forward = matches12.get(i);
        DMatch backward = matches21.get(forward.trainIdx);
        if(backward.trainIdx == forward.queryIdx)
            good_matches.add(knn_matches.get(i));   //k=2
    }

    return good_matches;
}



private List<MatOfDMatch> ratioCheck(List<MatOfDMatch> knn_matches, float ratio) {

    List<MatOfDMatch> good_matches = new ArrayList<MatOfDMatch>();

    for(int i=0; i<knn_matches.size(); i++)
    {
        List<DMatch> subList = knn_matches.get(i).toList();

        if(subList.size()>=2)
        {
            Float first_distance = subList.get(0).distance;
            Float second_distance = subList.get(1).distance;

            if((first_distance/second_distance) <= ratio)
                good_matches.add(knn_matches.get(i));


        }

    }

    return good_matches;
}