为什么以及如何应用阈值来获得更好的匹配特征

Why and how apply thresholding to get better matched features

在下面的代码中,我正在使用 BRUTFORCE 算法进行描述符匹配。我阅读了一些教程,但它们是用 C++ 编写的,我发现,总是在匹配过程之后,来自

的结果 MatOfDMatch 对象
.match(query_desc, train_desc, MatOfDMatch objec)

应该如下转换为DMatch对象

List<DMatch> dMtchList = matDMatch.toList();

并且 dMtchList 应该按升序排序,然后应用阈值处理,然后将 dMtchList 对象转换为 MatOfDMatch。

我的问题是,为什么我们需要应用阈值,因为我可以对从 .match(..,..,..) 方法返回的原始匹配进行升序排序,以及阈值如何增强匹配。

**代码*:

private static void descriptorMatcher() {
    // TODO Auto-generated method stub
    MatOfDMatch matDMatch = new MatOfDMatch();//empty MatOfDmatch object
    dm.match(matFactory.getComputedDescExtMatAt(0), matFactory.getComputedDescExtMatAt(1), matDMatch);//descriptor extractor of the query and the train image are used as parameters 
    matFactory.addRawMatchesMatDMatch(matDMatch);

    /*writing the raw MatDMatches*/
    Mat outImg = new Mat();
    Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getRawMatchesMatDMatchList()), 
            outImg);
    matFactory.addRawMatchedImage(outImg);
    MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.RAW_MATCHED_IMAGE), MatFactory.lastAddedObj(matFactory.getRawMatchedImageList()));//this produce img_2 below posted

    /*getting the top 10 shortest distance*/
    List<DMatch> dMtchList = matDMatch.toList();
    List<DMatch> goodDMatchList = MatFactory.getTopGoodMatches(dMtchList, 0, 10);//this method sort the dMatchList ascendingly and picks onlt the top 10 distances and assign these values to goodDMatchList

    /*converting the goo DMatches to MatOfDMatches*/
    MatOfDMatch goodMatDMatches = new MatOfDMatch();
    goodMatDMatches.fromList(goodDMatchList);
    matFactory.addGoodMatchMatDMatch(goodMatDMatches);

    /*drawing the good matches and writing the good matches images*/
    Features2d.drawMatches(matFactory.getMatAt(0), matFactory.getMatKeyPtsAt(0), matFactory.getMatAt(1), matFactory.getMatKeyPtsAt(1), MatFactory.lastAddedObj(matFactory.getGoodMatchMatDMatchList()), 
            outImg);
    MatFactory.writeMat(FilePathUtils.newOutputPath(SystemConstants.GOOD_MATCHED_IMAGE), outImg);// this produce img_1 below posted
}

过滤可以让您精简匹配项,只保留最好的匹配项,并让您可以控制决定什么是好的匹配项,这也可以为您的结果赋予权重。

没有什么能阻止您选择前 10 个最接近的匹配项,但如果不将它们与某些标准或准则进行比较,它们就没有任何意义。

通过将自己限制在前 N 个匹配项中,您可能还会错过更多潜在的匹配项,尤其是当您从提取中返回了成百上千个匹配项时。

假设您正在比较两张图片 A 和 B。

如果您总共收到 1000 场比赛并且其中 900 场通过了您的一系列 threshold/filtering 检查,您可以说它们很可能相似。如果只有 50 个通过,则两张图片根本不相似。

但是,如果您只看前 10 名匹配项,您无法真正确定多少,如果图像或相似,它们可能是许多强匹配中最好的,或者如果图像非常不同,它们可能是许多弱匹配中最好的.

编辑 - 距离

距离是衡量两个关键点之间相似度的指标,距离越大相似度越低,距离越小相似度越高。

在您查看的示例中,最大和最小距离初始化如下:

[http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html]

double max_dist = 0; double min_dist = 100;

这只是为了用匹配列表中存在的实际 min/max 值更新它们。如果最小值从 0 开始,它可能永远不会被覆盖,对于最大距离,反之亦然。

  for( int i = 0; i < descriptors_1.rows; i++ ){ 
    double dist = matches[i].distance;
    if( dist < min_dist ) min_dist = dist;
    if( dist > max_dist ) max_dist = dist;