OpenCV - Object matching using SURF descriptors and BruteForceMatcher

38,449

Solution 1

The problem was in using Brute Force Matcher only, I found methods to obtain a set of good matches between two views at "OpenCV 2 Computer Vision Application Programming Cookbook"

Ch9: Matching images using random sample consensus

They are using K-Nearest Neighbor and RANSAC

And thanks

Solution 2

For removing outliers RANSAC + homography is a good method when comparing two planar images.

Homography is the model that RANSAC will try to use to compare points from both images and it will find the best set of points that better fit the projection model of the homography (the transformation from one plane to another).

cv::findHomography(srcPoints,dstPoints, RANSAC, status);

The function above will return an array status that has a 1 for indices considered inliers and 0 for indices considered outliers, so you can remove outliers by checking this status array.

Solution 3

You need to modify your Hessian, 2500 is too much. Try 50. When you use a big Hessian, the result is a lot of keypoints, resulting some unnecessary. Another information about SURF is that your marker need to be more rich, with more details.

Share:
38,449
khateeb
Author by

khateeb

Updated on July 05, 2022

Comments

  • khateeb
    khateeb almost 2 years

    I have a question about objects matching with OpenCV. I'm useing SURF algorithm implemented in opencv 2.3 to first detect features on each image, and then extracting the descriptors of these features. The problem in matching using Brute Force Matcher, I don't know how I judge that the two images are matched or not that's as when I'm using two different images there are lines between descriptors in the two images!

    These outputs of my code, either the two images -I compare with them - are similar or different, the result image indicate that the two images are matched.

    The question is: How can I distinguish between the two images?

    True matching:

    http://store1.up-00.com/Jun11/hxM00286.jpg

    False matching!! :

    http://store1.up-00.com/Jun11/D5H00286.jpg

    My code:

    Mat image1, outImg1, image2, outImg2;
    
    // vector of keypoints
    vector<KeyPoint> keypoints1, keypoints2;
    
    // Read input images
    image1 = imread("C://Google-Logo.jpg",0);
    image2 = imread("C://Alex_Eng.jpg",0);
    
    SurfFeatureDetector surf(2500);
    surf.detect(image1, keypoints1);
    surf.detect(image2, keypoints2);
    drawKeypoints(image1, keypoints1, outImg1, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    drawKeypoints(image2, keypoints2, outImg2, Scalar(255,255,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
    
    namedWindow("SURF detector img1");
    imshow("SURF detector img1", outImg1);
    
    namedWindow("SURF detector img2");
    imshow("SURF detector img2", outImg2);
    
    SurfDescriptorExtractor surfDesc;
    Mat descriptors1, descriptors2;
    surfDesc.compute(image1, keypoints1, descriptors1);
    surfDesc.compute(image2, keypoints2, descriptors2);
    
    BruteForceMatcher<L2<float>> matcher;
    vector<DMatch> matches;
    matcher.match(descriptors1,descriptors2, matches);
    
    nth_element(matches.begin(), matches.begin()+24, matches.end());
    matches.erase(matches.begin()+25, matches.end());
    
    Mat imageMatches;
    drawMatches(image1, keypoints1, image2, keypoints2, matches, imageMatches, Scalar(255,255,255));
    
    namedWindow("Matched");
    imshow("Matched", imageMatches);
    
    cv::waitKey();
    return 0;
    
  • Admin
    Admin over 11 years
    This book turns out to be pretty useful!
  • Mustafa
    Mustafa about 11 years
    Using LMEDS (Calib3d.LMEDS on Android) gives better results to me, I do not know why, in my course project, RANSAC in Matlab gave very nice results. But definetely, removing outliners is a must!