使用BruteForceMatcher在两个不同的运行时使用相同的输入,OpenCV不同的输出结果

时间:2011-07-04 15:03:06

标签: c++ opencv matching brute-force

简介: 首先,作为介绍,我很自豪地在StackOverflow上提出我的第一个问题。我希望我能帮助别人,就像他们帮助我一样。

上下文: 我正在开发一个使用SURF算法搜索图像中的要素的应用程序。我计算关键点,然后用SURF提取描述符。然后,我使用基于欧几里德距离的强力匹配器来匹配图像1的描述符和图像2。 这是问题,我没有得到相同的结果与2个不同的程序运行(使用相同的图像,我应该精确:p)。

输出 这是输出,

第一场比赛的第一场比赛是在3620的第一场比赛中

0:  0   89  0.292352
1:  1   997 0.186256
2:  2   1531    0.25669
3:  3   2761    0.24148
4:  4   2116    0.286187
5:  5   2996    0.201048
6:  6   3109    0.266272
7:  7   2537    0.17112
8:  8   2743    0.211974
9:  9   2880    0.208735
10: 10  2167    0.269716
11: 11  2431    0.164508
12: 12  1474    0.281442
13: 13  1867    0.161129
14: 14  329 0.18388
15: 15  1580    0.229825
16: 16  1275    0.254946
17: 17  1749    0.203006
18: 18  305 0.221724
19: 19  1501    0.224663
20: 20  917 0.20708

20场比赛中的第二场比赛,3620场比赛

0:  0   1455    0.25669
1:  1   963 0.186256
2:  2   3008    0.150252
3:  3   2936    0.24148
4:  4   2172    0.286187
5:  5   2708    0.211974
6:  6   730 0.185199
7:  7   3128    0.266272
8:  8   750 0.181001
9:  9   2272    0.17112
10: 10  2842    0.208735
11: 11  55  0.229677
12: 12  2430    0.269716
13: 13  2360    0.164508
14: 14  1497    0.229825
15: 15  2443    0.254148
16: 16  1784    0.161129
17: 17  1209    0.254946
18: 18  311 0.18388
19: 19  944 0.228939
20: 20  533 0.221724

代码:以下是我使用的代码的一部分

SurfFeatureDetector detector(400);
vector<KeyPoint> keypoints1, keypoints2;
detector.detect(img1, keypoints1);
detector.detect(img2, keypoints2);

SurfDescriptorExtractor extractor;
Mat descriptors1, descriptors2;
extractor.compute(img1, keypoints1, descriptors1);
extractor.compute(img2, keypoints2, descriptors2);

vector<DMatch> filteredMatches;
matching(descriptors1,descriptors2,filteredMatches,1);

这是匹配函数

void crossCheckMatching( const Mat& descriptors1, const Mat& descriptors2,
                     vector<DMatch>& filteredMatches12, int knn=1 )
{
    BruteForceMatcher<L2<float>> matcher;
    filteredMatches12.clear();
    vector<vector<DMatch> > matches12, matches21;

    matcher.knnMatch( descriptors1, descriptors2, matches12, knn );
    matcher.knnMatch( descriptors2, descriptors1, matches21, knn );

    debug_writeMatches("D:/jmartel/exec2-log.txt",matches12);
    ...
}

结论: SURF算法提供“逼真”输出,部分通过2个运行时检测到的关键点数量来证明相同的2个图像。 BruteForceMatcher给了我非常奇怪的输出,它由日志文件证明,并且我可以输出的图像清楚地显示它在两个运行时以相同的方式不匹配。

我还在GPU上实现了所有这些代码,我的观察也很相似。但是,SURF在GPU上提供了更多的点(具有相同的参数)。

如果我们仔细观察这些点,一些距离完全相似,这可能是奇怪的(即使两组点之间的描述符可以相等......)。这是这对夫妇的例子

  (runtime 1) 1: 1 997 0.186256
/ (runtime 2) 1:1 963 0.186256 

甚至是陌生人

  (runtime 1) 14: 14  329 0.18388
/ (runtime 2) 18: 18  311 0.18388

OpenCV2.0 Doc并没有从我读到的内容中说出任何特别有趣的内容。 See BruteForceMatcher C++ Documentation for OpenCV2.1 here

如果您有任何解释,或者我可以在代码中更改任何内容,我会很高兴。 谢谢你的帮助。

于连

3 个答案:

答案 0 :(得分:6)

你能检查一下这个特色的顺序吗?如果您有多个CPU,则代码可以并行运行,因此功能的顺序不同(每次都是这样)。

答案 1 :(得分:0)

你是否可以更具体一点,即使它并行运行,为什么算法会给出不同的输出?

但是你告诉我的是,我作为例子提供的输出并不相关,因为存在并行执行,它可以解释为什么在某些情况下距离完全相似=> 2个运行时= 2个相同的描述符对,具有2个不同的运行时处理索引= 2个不同的输出顺序... 但是,仍然存在这样的问题:它没有给出相同的图像结果...我看到不同的对被链接为什么要因为并行性而改变?没有别的东西吗?

答案 2 :(得分:0)

如果差异非常小,那么使用float vs. double可能会有所不同。

您的非确定性可能源于使用指针地址作为哈希键,即使这只是猜测。