OpenCV разные выходные результаты с использованием BruteForceMatcher для двух разных сред выполнения с одинаковым вводом - PullRequest
4 голосов
/ 04 июля 2011

Введение: Во-первых, и как вступление, я довольно "горжусь", чтобы задать свой первый вопрос о StackOverflow.Я надеюсь, что смогу помочь другим людям так же, как они помогают мне.

Контекст: Я разрабатываю приложение, которое ищет элементы изображения с использованием алгоритма SURF.Я вычисляю ключевые точки и извлекаю дескрипторы с помощью SURF.Затем я использую метод сравнения грубой силы, основанный на евклидовом расстоянии, чтобы сопоставить дескрипторы изображения 1 с изображением 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 времени выполнения с теми же двумя изображениями.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 не говорит ничего особенно интересного из того, что я прочитал. См. Документацию BruteForceMatcher C ++ для OpenCV2.1 здесь

Если у вас есть какие-либо объяснения или что-то, что я мог бы изменить в коде, я буду рад.Спасибо за вашу помощь.

Жюльен,

Ответы [ 3 ]

6 голосов
/ 16 июля 2011

Не могли бы вы проверить порядок подателей?Если у вас несколько процессоров, код может работать параллельно, поэтому функции не в том же порядке (для каждого времени).

0 голосов
/ 25 июля 2011

Если различия действительно малы, то использование float против double может иметь значение.

Ваш недетерминизм может возникнуть из-за использования адресов указателей в качестве ключей хеша, даже если это всего лишь предположение.

0 голосов
/ 20 июля 2011

Не могли бы вы быть более конкретным, даже если он работает параллельно, почему алгоритм должен давать разные выходные данные?

Но вы говорите мне, что выходные данные, которые я привел в качестве примеров, не актуальны, поскольку существует параллельное выполнение, это может объяснить, почему расстояние в некоторых случаях точно одинаково => 2 времени выполнения = 2 одинаковая пара дескрипторов с 2 разный индекс времени выполнения обработки = 2 разный порядок выводов ... Тем не менее, все еще существует проблема, заключающаяся в том, что он не дает тот же результат изображения ... я вижу, что разные пары связаны, почему он должен быть изменен из-за параллелизма? Есть ли что-то еще?

...