1

I'm trying to match SURF keypoints from a template image to what is being shown in a video feed but I am getting the following errors when trying to call FlannBasedMatcher.

captureFromCam.cpp: In function ‘void matchAndDrawKeypoints(cv::Mat, IplImage*)’:
captureFromCam.cpp:110:55: error: no matching function for call to ‘cv::FlannBasedMatcher::match(cv::FileNode&, cv::Mat&, std::vector<cv::DMatch>&)’
captureFromCam.cpp:110:55: note: candidates are:
In file included from /usr/local/include/opencv/cv.h:68:0,
                 from captureFromCam.cpp:2:
/usr/local/include/opencv2/features2d/features2d.hpp:1110:18: note: void cv::DescriptorMatcher::match(const cv::Mat&, const cv::Mat&, std::vector<cv::DMatch>&, const cv::Mat&) const
/usr/local/include/opencv2/features2d/features2d.hpp:1110:18: note:   no known conversion for argument 1 from ‘cv::FileNode’ to ‘const cv::Mat&’
/usr/local/include/opencv2/features2d/features2d.hpp:1128:18: note: void cv::DescriptorMatcher::match(const cv::Mat&, std::vector<cv::DMatch>&, const std::vector<cv::Mat>&)
/usr/local/include/opencv2/features2d/features2d.hpp:1128:18: note:   no known conversion for argument 1 from ‘cv::FileNode’ to ‘const cv::Mat&’

I am trying to do this by reading in the image, calculating the keypoints and descriptors and saving them in a yml format like so:

// code to detect features/descriptors
...
  cv::FileStorage fs(fileNamePostCut + ".yml", cv::FileStorage::WRITE);
  write(fs, fileNamePostCut + "Keypoints_1", keypoints_1);
  write(fs, fileNamePostCut + "Descriptors_1", img_descriptors_1);
  fs.release();

In a separate function I am then trying to load the keypoints and descriptors and compare them to the values calculated for the video stream:

matchAndDrawKeypoints (cv::Mat img_1, IplImage* frames)
      std::vector<cv::KeyPoint> templateKeypoints;
      std::vector<cv::KeyPoint> templateDescriptor;
      cv::FileStorage fs2("VWlogo.yml", cv::FileStorage::READ);
      cv::FileNode kptFileNode = fs2["VWlogoKeypoints_1"];
      read(kptFileNode, templateKeypoints);
      cv::FileNode desFileNode = fs2["VWlogoDescriptors_1"];
      read(desFileNode, templateDescriptor);
      fs2.release();
      cv::FlannBasedMatcher matcher;
      std::vector<cv::DMatch> matches;
      matcher.match(desFileNode, img_descriptors_1, matches);

I'm assuming the problem is either the descriptors not being loading correctly from the yml file or else the descriptors for the video feed are not being passed in correctly.

Below is just some extra information on the flow of information:

main() calls makeitgrey(frame) calls detectKeypoints(grey_frame) which returns to makeitgrey() which returns to main() which then calls matchAndDrawKeypoints (img_1, frames)

EDIT: Code where keypoints are computed and declarations.

cv::Mat img_keypoints_1;
cv::Mat img_1;
cv::Mat img_descriptors_1;
std::vector<cv::KeyPoint> keypoints_1;
std::vector<cv::KeyPoint> descriptors_1;

main() passes video to makeitgrey() which passes to:

IplImage* detectKeypointsImage (IplImage* img_1) {
  int minHessian = 400;
  cv::SurfFeatureDetector detector(minHessian);
  detector.detect(img_1, keypoints_1);
  drawKeypoints(img_1, keypoints_1, img_keypoints_1);
  cv::SurfDescriptorExtractor extractor;
  extractor.compute(img_1, keypoints_1, img_descriptors_1);
  return img_1;
}

The template image is passes in as a command line arg which is then passed to detectTemplateKeypoints(img_1, argv[1]); which is shown in original post.

Colin747
  • 4,955
  • 18
  • 70
  • 118
  • try `matcher.match(templateDescriptor, descriptors_1, matches);` I assume that you wanted to pass the loaded descriptors to the function and not the storage file node from that you have read the descriptors already – Micka Jan 14 '15 at 10:34
  • That resulted in a very similar error. Instead of `no known conversion for argument 1 from ‘cv::FileNode’ to ‘const cv::Mat&’` I got `no known conversion for argument 1 from ‘std::vector’ to ‘const cv::Mat&’` – Colin747 Jan 14 '15 at 10:36
  • The loaded descriptors are to be passed to the function yes. – Colin747 Jan 14 '15 at 10:37
  • change `std::vector templateDescriptor;` to the type that you used when writing to file node. Probably somethign like `std::vector templateDescriptor;` I mean the type of `descriptors_1` at the moment you've written it. – Micka Jan 14 '15 at 10:37
  • `std::vector keypoints_1;` `std::vector descriptors_1;` are the two vectors I used for writing which should be the same type? Or have I misunderstood? – Colin747 Jan 14 '15 at 10:40
  • I am pretty sure that descriptors are not of type `cv::Keypoint`, so you might have some mistake there. I'm even pretty sure that it should be `cv::Mat` for descriptor. Can you please share the line of code where you compute the keypoints and the descriptors (including their parameter declarations)? – Micka Jan 14 '15 at 10:45
  • have a look at this example and how they declare/use descriptors during computation: http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html – Micka Jan 14 '15 at 10:47
  • Hopefully that is the extra code that you asked for. – Colin747 Jan 14 '15 at 10:49
  • does your `detectKeypointsImage` work if you try to access the descriptors? I think it shouldn't... change to `cv::Mat descriptors_1;` and `cv::Mat templateDescriptor;` and everything should work, if I see right. – Micka Jan 14 '15 at 10:59
  • That compiles with zero errors, thank you very much for your help. – Colin747 Jan 14 '15 at 11:04
  • 1
    If you would like to add an answer I'll gladly accept? – Colin747 Jan 14 '15 at 12:57

1 Answers1

2

There are two problems in the code:

  1. std::vector<cv::KeyPoint> templateDescriptor; is not the right type for descriptors. For descriptor computation. In the sample code from http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html you can see, that descriptors for a bunch of keypoints are typically type cv::Mat. So change it to cv::Mat templateDescriptor; and cv::Mat descriptors_1;

  2. matcher.match(desFileNode, img_descriptors_1, matches); must be matcher.match(templateDescriptor, img_descriptors_1, matches); instead, since you want to match the descriptors and not the file storage node.

Micka
  • 19,585
  • 4
  • 56
  • 74