Отображение соответствий из соотношения расстояний до ближайших соседей

В openCV я адаптировал этот учебный код в своем приложении.

http://docs.opencv.org/2.4.2/doc/tutorials/features2d/feature_homography/feature_homography.html#feature-homography

Я пытался обрезать совпадения, используя коэффициент расстояния до ближайшего соседа, чтобы отображать совпадения только выше определенного порогового значения.

  double ratio = 0.9;
  std::vector< vector<DMatch > > nnMatches;
  std::vector< DMatch > good_NNmatches;
  matcher.knnMatch(descriptors_scene, descriptors_object, nnMatches, 2 );

  for(int k = 0; k < nnMatches.size(); k++)
  {
      if(nnMatches[k][0].distance / nnMatches[k][1].distance > ratio)
      {
          good_NNmatches.push_back(nnMatches[k][0]);
      }
  }

Затем я пытаюсь нарисовать совпадения в good_NNmatches, используя тот же метод, что и в учебнике, но получаю следующую ошибку:

OpenCV Error: Assertion failed (i1 >= 0 && i1 < static_cast<int>(keypoints1.size())) in     drawMatches, file /Users/cgray/Downloads/opencv-2.4.6/modules/features2d/src/draw.cpp, line 207
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /Users/cgray/Downloads/opencv-2.4.6/modules/features2d/src/draw.cpp:207: error: (-215) i1 >= 0 && i1 < static_cast<int>(keypoints1.size()) in function drawMatches

При попытке вызвать drawMatches с использованием good_nnMatches вместо good_matches, как описано в руководстве.

drawMatches( roiImg, keypoints_object, compare, keypoints_scene,
                     good_NNmatches, img_matches, Scalar::all(-1), Scalar::all(-1),
                     vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

person Tom smith    schedule 17.04.2014    source источник
comment
Я не знаю, является ли это причиной вашей проблемы, но ваше условие неверно. Вы должны добавить совпадение в good_NNmatches, если nnMatches[k][0].distance / nnMatches[k][1].distance < ratio.   -  person BConic    schedule 18.04.2014
comment
Это не решило ошибку утверждения, но теперь я изменил условие и нашел решение проблемы, спасибо.   -  person Tom smith    schedule 18.04.2014
comment
Почему бы нам не удалить УТВЕРЖДЕНИЕ ИЗ DRAW.CPP??????????   -  person Hani Goc    schedule 04.12.2014


Ответы (3)


У меня была такая же проблема. В моем случае я делал

cv::Mat output;
drawMatches( smallimg, keyptsSm, bigimg, keyptsBg, matchesBig2Small, output );

Где совпадения matchesBig2Small были рассчитаны от bigimg до smallimg

std::vector<cv::DMatch> matchesBig2Small; 
//match from bigimg to smallimg

Таким образом, ошибка, которую вы получили, на самом деле говорит о том, что она ищет индекс ключевой точки в smallimg, который на самом деле относится ко второму изображению, которое больше, поэтому вы превышаете размер smallimg. Поэтому либо измените вызов drawMatches на:

drawMatches( bigimg, keyptsBg, smallimg, keyptsSm, matchesBig2Small, output );

Или измените способ вычисления совпадений с smallimg на bigimg, чтобы вместо matchesBig2Small у вас было matchesSmall2Big, и тогда вызов был бы таким:

std::vector<cv::DMatch> matchesSmall2Big; 
//match from smallimg to bigimg
drawMatches( smallimg, keyptsSm, bigimg, keyptsBg, matchesSmall2Big, output );
person adinutzyc21    schedule 17.06.2014
comment
Спасибо, это была именно моя ошибка. - person Avio; 13.01.2017

Хорошо, после некоторых проб и ошибок я, похоже, решил эту проблему.

Я изменил метод drawMatches, чтобы поменять местами «roiImg» и ключевые точки на «сравнить» и ключевые точки.

drawMatches(compare, keypoints_scene, roiImg, keypoints_object,
               good_NNmatches, img_matches, Scalar::all(-1), Scalar::all(-1),
               vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

Это остановило ошибку утверждения. Но из-за перестановки значений, когда дело дошло до извлечения ключевых точек, мне также пришлось внести некоторые изменения. trainIdx и queryIdx также были заменены местами, чтобы учесть предыдущие изменения.

obj.push_back( keypoints_object[ good_NNmatches[i].trainIdx ].pt );
scene.push_back( keypoints_scene[ good_NNmatches[i].queryIdx ].pt );
person Tom smith    schedule 18.04.2014

Я сделал это, и у меня нет никаких проблем, я надеюсь, что этот код может вам помочь

double NNDR;

    for(int i=0;i<(int)ORB_ORB_matches.size(); i++){

        NNDR= ( ORB_ORB_matches[i][0].distance/ORB_ORB_matches[i][1].distance );

        if(NNDR <= 0.9){

            ORB_single_matches.push_back (ORB_ORB_matches[i][0]);

        }

    }
drawMatches( image_1, keypoints_1, image_2, keypoints_2, ORB_single_matches, img_matches,Scalar::all(-1),Scalar::all(-1),vector<char>(),`enter code here`          DrawMatchesFlags::DRAW_RICH_KEYPOINTS|DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
person Omar    schedule 15.04.2018