OpenCV 在具有相同输入的两个不同运行时使用 BruteForceMatcher 得到不同的输出结果

发布于 2024-11-18 04:22:30 字数 3337 浏览 4 评论 0原文

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

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

输出: 以下是输出,

第一个运行时间为 3620 个匹配中的 20 个匹配,

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

第二个运行时间为 3620 个匹配中的第 20 个匹配

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 上提供了更多的点(具有相同的参数)。

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

  (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 文档没有说任何我读到的特别有趣的内容。 在此处查看 OpenCV2.1 的 BruteForceMatcher C++ 文档

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

朱利安,

Intro :
First and as an introduction, i am quite "proud" to ask my first question on StackOverflow. I hope I'll be able to help other people as much as they help me.

Context :
I am developping an application that searches for features in an image using a SURF algorithm. I compute the keypoints and I extract the descriptors with SURF. Then, I use a bruteforce matcher based on euclidian distance to match descriptors of image 1 with image 2.
Here is the problem, i don't get the same results with 2 different runs of the program (using the same image, should I precise :p).

Outputs :
Here are the outputs,

1st runtime on the 20 first matches out of 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

2nd runtime on the 20 first matches out of 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

Code : Here is a part of the code i use

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);

Here is the matching function

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);
    ...
}

Conclusions : The SURF algorithm gives "realistic" outputs, it is partly proved by the same number of detected keypoints over 2 runtimes with the same 2 images. The BruteForceMatcher gives me really strange output, it is proved by the log file, and with the image i can output which clearly shows it does not match in the same way over two runtimes.

I also implemented all this code on GPU and my observations are similar. However, SURF provides more point on GPU (with the same parameters).

If we look carefully to the points, some distances are exactly similar, which can be possible but strange (even if the descriptors between the 2 set of points can be equal...). It's the example of the couple

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

or even stranger

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

The OpenCV2.0 Doc does not say anything particularly interesting from what i read.
See BruteForceMatcher C++ Documentation for OpenCV2.1 here

If you have any explanation, or anything i could change in the code, I'll be glad.
Thanks for your help.

Julien,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

很酷又爱笑 2024-11-25 04:22:30

你能检查一下功能的顺序吗?如果您有多个 CPU,代码可能会并行运行,因此功能的顺序不同(每次)。

Could you check the order of the featuers? If you have multiple CPUs, the code may run parallel so the features are not in the same order (for each time).

转身以后 2024-11-25 04:22:30

您能否更具体一点,即使它并行运行,为什么算法应该给出不同的输出?

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

Could you be a little bit more specific, even if it runs in parallel why should the algorithm give different outputs ?

But what you tell me is that the outputs I gave as examples are not relevant as there is a parallel execution, it could explain why the distance in certain cases are exactly similar => 2 runtimes = 2 same pair of descriptors with 2 different runtime index of processing = 2 different order of outputs...
However, there is still the problem that it doesn't give the same Image result... i see different pairs are linked why should it be changed because of parallelism ? Isn't there something else ?

你的他你的她 2024-11-25 04:22:30

如果差异确实很小,那么使用 float 与 double 可以产生不同的效果。

您的不确定性可能是由于使用指针地址作为散列键而引起的,即使这只是一个猜测。

If differences are really small then using float vs. double can make a difference.

Your non-determinism might arise from use of pointer addresses as hash keys, even though this is just a guess.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文