はじめに: 最初に紹介として、私は StackOverflow に関する最初の質問をすることを非常に「誇りに思っています」。他の人が私を助けてくれるのと同じくらい、私も他の人を助けることができたらいいなと思っています。
コンテキスト : SURF アルゴリズムを使用して画像内の特徴を検索するアプリケーションを開発しています。キーポイントを計算し、SURF で記述子を抽出します。次に、ユークリッド距離に基づくブルートフォース マッチャーを使用して、画像 1 の記述子を画像 2 と一致させます。ここに問題があります。プログラムを 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 試合で 2 回目の実行
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 は本当に奇妙な出力を提供します。これはログ ファイルによって証明されており、2 つのランタイムで同じように一致しないことを明確に示す出力可能な画像を使用できます。
また、このすべてのコードを 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 Doc には、私が読んだ内容から特に興味深いことは何も書かれていません。 ここで OpenCV2.1 の BruteForceMatcher C++ ドキュメントを参照してください。
説明があれば、またはコードを変更できるものがあれば、喜んでいます。ご協力いただきありがとうございます。
ジュリアン