OpenCV, соответствие функций коду из учебника

Я скопировал код Сопоставление функций с FLANN с учебника по OpenCV и внес следующие изменения:

  • Я использовал функции SIFT вместо SURF;
  • Я изменил проверку на "хорошее совпадение". Вместо

    if( matches[i].distance < 2*min_dist )
    

Я использовал

    if( matches[i].distance <= 2*min_dist )

в противном случае я получал бы нулевые хорошие совпадения при сравнении изображения с самим собой.

  • Измененный параметр при рисовании ключевых точек:

    drawMatches( img1, k1, img2, k2,
                     good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                     vector<char>(), DrawMatchesFlags::DEFAULT);
    

Я извлек SIFT из всех изображений в папке Ireland INRIA-Holidays dataset. Затем я сравнивал каждое изображение со всеми остальными и рисовал совпадения.

Однако есть странная проблема, с которой я никогда не сталкивался ни с какими другими реализациями SIFT/Matcher, которые я использовал в прошлом:

  • совпадения для изображения, которое я сопоставил с самим собой, хороши. Каждая ключевая точка отображается на себя, за исключением некоторых. См. Изображение выше. Image matched against itselft
  • Когда я сопоставляю я с другим изображением J (с J не равным I), многие точки отображаются на один и тот же. Ниже приведены некоторые примеры. MatchesMatchesMatches

Есть ли кто-нибудь, кто использовал один и тот же код из учебника OpenCV и может сообщить о моем опыте?

Ответ 1

Ознакомьтесь с примером matcher_simple.cpp. Он использует переборку грубой силы, которая, похоже, работает очень хорошо. Вот код:

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

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

// matching descriptors
BFMatcher matcher(NORM_L2);
vector<DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);

// drawing the results
namedWindow("matches", 1);
Mat img_matches;
drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
imshow("matches", img_matches);
waitKey(0);