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

时间:2015-04-09 11:45:41

标签: java opencv javacv opencv3.0 opencv4android

在下面的代码中,我正在使用BRUTFORCE算法进行描述符匹配。我读了som教程,但是他们是用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
}

1 个答案:

答案 0 :(得分:1)

过滤可以让你精简你的比赛,只留下最好的比赛,并让你控制决定什么是一个好的比赛它也可以给你的结果带来重量。

没有什么可以阻止你选择前10名最接近的比赛,但如果他们没有与某些标准或指导方针进行比较,他们就没有任何意义。

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

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

如果您总共收到1000场比赛,其中900场比赛通过了一系列的门槛/过滤检查,那么他们很可能会两者相似。如果只有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开始为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;