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.
There are two problems in the code:
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;
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.