Search code examples
c++opencvfeature-detection

Drawing matches from Nearest Neighbour Distance Ratio


In openCV I have adapted this tutorial code in my application

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

I have been trying to prune the matches using the Nearest Neighbour Distance Ratio to only draw matches above a certain threshold value.

  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]);
      }
  }

I am then trying to draw the matches in good_NNmatches using the same method demonstrated in the tutorial but I get the following error:

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

When trying to call drawMatches using good_nnMatches instead of good_matches as described in the tutorial.

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

Solution

  • Ok after some trial and error I appear to have solved this issue now.

    I have changed the drawMatches method to swap the "roiImg" and key points with "compare" and key points.

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

    This stopped the assertion error. But due to swapping the values around when it came to retrieving the key points I also had to make some changes. trainIdx and queryIdx have also been swapped to account for the previous changes made.

    obj.push_back( keypoints_object[ good_NNmatches[i].trainIdx ].pt );
    scene.push_back( keypoints_scene[ good_NNmatches[i].queryIdx ].pt );