1 | initial version |
As R. Saracchini pointed independently, if someone use a FLANN matcher, the descriptors must be in the CV_32F (float) format. For binary descriptors, a hamming matcher should be used, as in the following. Here is a working code for using BRISK in OpenCV 3 (Windows, Visual Studio 2012)
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat objectImg = imread("PATH_OF OBJECT_CHOOSE YOUR OWN", cv::IMREAD_GRAYSCALE);
Mat sceneImg = imread("PATH_OF SCENE/QUERY_CHOOSE YOUR OWN", cv::IMREAD_GRAYSCALE);
if( !objectImg.data || !sceneImg.data )
{
printf( " No image data \n " );
return -1337;
}
std::vector<cv::KeyPoint> objectKeypoints;
std::vector<cv::KeyPoint> sceneKeypoints;
cv::Mat objectDescriptors;
cv::Mat sceneDescriptors;
//////////////////////////////////////
// Object: keypoint descriptors computing
cv::Ptr<cv::BRISK> ptrBrisk = cv::BRISK::create();
ptrBrisk->detect(objectImg, objectKeypoints);
ptrBrisk->compute(objectImg,objectKeypoints,objectDescriptors);
//////////////////////////////////////
// Scene: keypoint descriptors computing
ptrBrisk->detect(sceneImg, sceneKeypoints);
ptrBrisk->compute(sceneImg,sceneKeypoints,sceneDescriptors);
std::vector< DMatch > matches;
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");
matcher->match( objectDescriptors, sceneDescriptors, matches );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < objectDescriptors.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
std::vector<cv::DMatch> good_matches;
for( int i = 0; i < objectDescriptors.rows; i++ )
{
if( matches[i].distance <= max(2*min_dist, 0.02) ) {
good_matches.push_back( matches[i]);
}
}
Mat allmatchs;
drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,touslesmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
imshow( "Matchs",allmatchs);
waitKey(0);
}
2 | No.2 Revision |
As R. Saracchini pointed independently, if someone use a FLANN matcher, the descriptors must be in the CV_32F (float) format. For binary descriptors, a hamming matcher should be used, as in the following. Here is a working code for using BRISK in OpenCV 3 (Windows, Visual Studio 2012)
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
int main( int argc, char** argv )
{
Mat objectImg = imread("PATH_OF OBJECT_CHOOSE YOUR OWN", cv::IMREAD_GRAYSCALE);
Mat sceneImg = imread("PATH_OF SCENE/QUERY_CHOOSE YOUR OWN", cv::IMREAD_GRAYSCALE);
if( !objectImg.data || !sceneImg.data )
{
printf( " No image data \n " );
return -1337;
}
std::vector<cv::KeyPoint> objectKeypoints;
std::vector<cv::KeyPoint> sceneKeypoints;
cv::Mat objectDescriptors;
cv::Mat sceneDescriptors;
//////////////////////////////////////
// Object: keypoint descriptors computing
cv::Ptr<cv::BRISK> ptrBrisk = cv::BRISK::create();
ptrBrisk->detect(objectImg, objectKeypoints);
ptrBrisk->compute(objectImg,objectKeypoints,objectDescriptors);
//////////////////////////////////////
// Scene: keypoint descriptors computing
ptrBrisk->detect(sceneImg, sceneKeypoints);
ptrBrisk->compute(sceneImg,sceneKeypoints,sceneDescriptors);
std::vector< DMatch > matches;
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");
matcher->match( objectDescriptors, sceneDescriptors, matches );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < objectDescriptors.rows; i++ )
{
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
std::vector<cv::DMatch> good_matches;
for( int i = 0; i < objectDescriptors.rows; i++ )
{
if( matches[i].distance <= max(2*min_dist, 0.02) ) {
good_matches.push_back( matches[i]);
}
}
Mat allmatchs;
drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,touslesmatchs,Scalar::all(-1), drawMatches(objectImg,objectKeypoints,sceneImg,sceneKeypoints,good_matches,allmatchs,Scalar::all(-1), Scalar::all(-1),vector<char>(),0);
imshow( "Matchs",allmatchs);
waitKey(0);
}