Ask Your Question

Which matcher is best for SURF?

asked 2012-10-18 13:40:07 -0600

Yiyi gravatar image

updated 2020-10-05 08:09:01 -0600

I am developing an android image recognition application and I had used SURF algorithm as detector and descriptor.There are many matchers like flannbased, bruteforce_hamming, bruteforce_hamminglut, bruteforce_sl2 and bruteforce_l1.Can I know which matcher is best for SURF.

edit retag flag offensive close merge delete

3 answers

Sort by ยป oldest newest most voted

answered 2012-10-19 09:29:59 -0600

alexcv gravatar image

updated 2012-10-21 09:24:21 -0600


We experimented various matchers with SURF.

FLANN is fast but... gives low performances in difficult context (heterogeneous/various) dataset.

Brute force matchers like L1 or L2 based distance give good results.

If you consider L2 based bruteforce matchers, consider L2 distance without the square root computation which does not introdue error in this matching case and allows less processing to be performed.

Typical use :

//Allocate your image descriptor and your matcher with a OpenCV pointer (do not care about the object delete step):

//-> 1. descriptor:

cv::Ptr<cv::DescriptorExtractor> _descExtractor = DescriptorExtractor_Custom::create("SURF");

/*-> 2. matcher: define a string keyword that shows which matcher to choose :

*BruteForce (it uses real L2 )

*BruteForce-SL2 (not in the documentation, BUT this is the one that skeeps the squared root !)






cv::Ptr<cv::DescriptorMatcher> _descMatcher = cv::DescriptorMatcher::create(keyword );

Finally, regarding good matches sorting, you should take a look at the RANSAC method that allows global a displacement identification and not corresponding matches pop out. Have a nice coding ;o)

edit flag offensive delete link more

answered 2012-10-19 07:49:16 -0600

imran gravatar image

In my opinion, it is FLANN-Based matcher however to get even better results you can filter the best matches accordingly. For example:

double max_dist = 0; double min_dist = 100;

//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
    double dist = matches[i].distance;
    if( dist < min_dist ) 
        min_dist = dist;
    if( dist > max_dist ) 
        max_dist = dist;
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );

//-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
//-- PS.- radiusMatch can also be used here.
vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
    if( matches[i].distance < 2*min_dist )
          good_matches.push_back( matches[i]); 
for( int i = 0; i < good_matches.size(); i++ )
    printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); 
edit flag offensive delete link more


imran, could you please explain what max and min distance represent? How does this filtering work?

dilgenter gravatar imagedilgenter ( 2012-11-08 09:31:19 -0600 )edit

with flann based matching my code breaks down. Is it maybe because the images are not same size?

Szippy gravatar imageSzippy ( 2012-11-11 05:48:13 -0600 )edit

@dilgenter max and min distance is the greatest and least distance from the a keypoint in one image that matched a keypoint in another image, respectively. So basically it in the code it refers to the matched keypoints only. The filtering works by only selecting those matched keypoints whose distance is less than 2 x the least distance.

imran gravatar imageimran ( 2012-11-13 15:50:11 -0600 )edit

@Szippy image sizes should not be a problem. There must be an other reason why it breaks down. Give me your email address and I'll send you some sample C++ code that works.

imran gravatar imageimran ( 2012-11-13 15:52:26 -0600 )edit

ok. My email address is [email protected], in the mean time I fixed the code, but am having trouble porting it to andtoid. I am using the ndk to acheive this.

Szippy gravatar imageSzippy ( 2012-11-14 10:30:58 -0600 )edit

answered 2012-11-11 05:47:08 -0600

Szippy gravatar image

Hello I am alsow working on an android project for image recognition of a set of images from sd card to the camera indicated ones. Have you completed youre work? Could you help me with a few questions?

My tought process is like this: 1: load all images from sd card, calculate their keypoints, then theirs descriptions in Mat, and store them in a List<mat> data container; 2: when the camera is initialized I get one image, turn it to grayscale, get their keyPoints, the descriptions, and do a Brute Force matching to he descriptor just calculated with a loop taking all previously loaded descriptors.

Then there is the MatOfDMath result, and there I have some issues. I am trying to get the good_matches List, but all the distances are 0 in the match result. I am saving the largest best_matches container to be the one witch is my image from the loaded ones, but it is not working. Any ideas?

edit flag offensive delete link more


@Szippy, I suggest you create a new question

imran gravatar imageimran ( 2012-11-13 15:53:54 -0600 )edit

@Szippy , do you solve your problem ?

Marwen Z gravatar imageMarwen Z ( 2013-04-16 04:41:18 -0600 )edit

yes I have.

Szippy gravatar imageSzippy ( 2013-08-10 02:49:53 -0600 )edit

Question Tools


Asked: 2012-10-18 13:40:07 -0600

Seen: 6,503 times

Last updated: Nov 11 '12