Ask Your Question
0

How to interpret the distances in matches of descriptors

asked 2016-02-05 03:32:17 -0600

thdrksdfthmn gravatar image

When doing a descriptor matching the DMatches have a distance, I would like to know if there is a logic behind and what is it? I am doing multiple matches on different groups of descriptors, and maybe the best-match is not entirely correct, so I would like to do a filter on distances and this will be easier if I would know the logic behind, without trying to understand the code if it is possible :p

Thanks

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2016-02-05 04:48:44 -0600

Eduardo gravatar image

updated 2016-02-05 06:43:30 -0600

It is the classical L2 distance for floating point descriptor and HAMMING like distance for binary descriptor.

You can check it with the following code:

  cv::Mat img1 = cv::imread("opencv-3.1.0/samples/data/aero1.jpg");
  cv::Mat img2 = cv::imread("opencv-3.1.0/samples/data/aero3.jpg");

  cv::Ptr<cv::Feature2D> sift = cv::xfeatures2d::SIFT::create();
  std::vector<cv::KeyPoint> trainKeypoints;
  cv::Mat trainDescriptors;
  sift->detectAndCompute(img1, cv::Mat(), trainKeypoints, trainDescriptors);

  std::vector<cv::KeyPoint> queryKeypoints;
  cv::Mat queryDescriptors;
  sift->detectAndCompute(img2, cv::Mat(), queryKeypoints, queryDescriptors);

  cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce");
  std::vector<cv::DMatch> matches;
  matcher->match(queryDescriptors, trainDescriptors, matches);
  std::cout << "matches[0]: trainIdx=" << matches[0].trainIdx << " ; queryIdx="
      << matches[0].queryIdx << " ; dist=" << matches[0].distance << std::endl;

  double my_dist = 0.0;
  for(int j = 0; j < trainDescriptors.cols; j++) {
    my_dist += (trainDescriptors.at<float>(matches[0].trainIdx, j) - queryDescriptors.at<float>(matches[0].queryIdx, j))
        * (trainDescriptors.at<float>(matches[0].trainIdx, j) - queryDescriptors.at<float>(matches[0].queryIdx, j));
  }
  std::cout << "my_dist=" << cv::sqrt(my_dist) << std::endl;

Edit: the type of distance that could be used is present in the documentation.

edit flag offensive delete link more

Comments

And as a parenthesis, what do you think is a big distance?

thdrksdfthmn gravatar imagethdrksdfthmn ( 2016-02-05 06:21:18 -0600 )edit
1

I would consider the Lowe ratio test or a cross-check validation (if the closest keypoint of A is B and if the closest keypoint of B is A, it could be considered as a match) rather than a threshold of the distance.

Eduardo gravatar imageEduardo ( 2016-02-05 06:36:32 -0600 )edit

Check out this answer from stackoverflow which explains distance in DMatch elegantly. https://stackoverflow.com/questions/1...

questerer gravatar imagequesterer ( 2017-12-20 01:42:26 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-02-05 03:32:17 -0600

Seen: 1,800 times

Last updated: Feb 05 '16