Ask Your Question

Revision history [back]

click to hide/show revision 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);

}

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

}