OpenCV различные выходные результаты с использованием BruteForceMatcher в течение двух различных сред выполнения с одинаковыми входными данными
Вступление: Во-первых, и в качестве введения, я очень горжусь тем, что задаю свой первый вопрос о StackOverflow. Я надеюсь, что смогу помогать другим людям так же, как они помогают мне.
Контекст: Я разрабатываю приложение, которое ищет объекты в изображении, используя алгоритм серфинга. Я вычисляю ключевые точки и извлекаю дескрипторы с помощью SURF. Затем я использую matcher bruteforce, основанный на евклидовом расстоянии, чтобы сопоставить дескрипторы изображения 1 с изображением 2. Вот проблема, я не получаю одинаковые результаты при 2-х разных запусках программы (используя один и тот же образ, я должен уточнить :p).
Выходные данные: Вот выходные данные,
1-е время выполнения на 20 первых матчах из 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
2-е время выполнения на 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 (с теми же параметрами).
Если мы посмотрим осторожно к точкам, некоторые расстояния точно такие же, что может быть возможно, но странно (даже если дескрипторы между 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 не говорит ничего особенно интересного из того, что я читал. смотрите документацию BruteForceMatcher C++ для OpenCV2. 1 здесь
Если у вас есть какие-либо объяснения, или что-нибудь, что я мог бы изменить в коде, Я буду очень рад. Спасибо за вашу помощь.
Жюльен,
3 ответа:
Не могли бы вы проверить порядок персонажей? Если у вас несколько процессоров, код может выполняться параллельно, поэтому функции не находятся в одном и том же порядке (для каждого времени).
Не могли бы вы быть немного более конкретными, даже если он работает параллельно, почему алгоритм должен давать разные выходные данные ?
Но вы говорите мне, что выходные данные, которые я привел в качестве примеров, не релевантны, поскольку существует параллельное выполнение, это может объяснить, почему расстояние в некоторых случаях точно такое же => 2 времени выполнения = 2 одинаковые пары дескрипторов с 2 различными индексами времени выполнения обработки = 2 различных порядка выходных данных... Тем не менее, есть еще проблема, что он не дает тот же результат изображения... я вижу, что разные пары связаны, почему это должно быть изменено из-за параллелизма ? Может быть, есть что-то еще ?