posha
posha

Reputation: 901

SURF Feature extraction and Keypoint match based on FlannBasedMatcher

Following is my code, which used to extract the features using SURF and which will match the points using flannBasedMatcher.

Mat object = imread("S6E0.bmp",  CV_LOAD_IMAGE_GRAYSCALE);

    if( !object.data )
    {
    // std::cout<< "Error reading object " << std::endl;
    return -2;
    }

    //Detect the keypoints using SURF Detector

    int minHessian = 500;

    SurfFeatureDetector detector( minHessian );

    std::vector<KeyPoint> kp_object;

    detector.detect( object, kp_object );

    //Calculate descriptors (feature vectors)
    SurfDescriptorExtractor extractor;

    Mat des_object;

    extractor.compute( object, kp_object, des_object );

    FlannBasedMatcher matcher;
    char key = 'a';
    //VideoCapture cap(0);

    namedWindow("Good Matches");

    std::vector<Point2f> obj_corners(4);

    //Get the corners from the object
    obj_corners[0] = cvPoint(0,0);
    obj_corners[1] = cvPoint( object.cols, 0 );
    obj_corners[2] = cvPoint( object.cols, object.rows );
    obj_corners[3] = cvPoint( 0, object.rows );

    Mat image = imread("S6E0.bmp", CV_LOAD_IMAGE_GRAYSCALE);
    Mat des_image, img_matches;

    std::vector<KeyPoint> kp_image;
    std::vector<vector<DMatch >> matches;

    std::vector<std::vector<cv::DMatch>> matches1;
    std::vector<std::vector<cv::DMatch>> matches2;
    std::vector<cv::DMatch> matches3;
    std::vector<DMatch > good_matches;
    std::vector<Point2f> obj;
    std::vector<Point2f> scene;

    std::vector<Point2f> scene_corners(4);

    Mat H;

    //cvtColor(frame, image, CV_RGB2GRAY);
    detector.detect( image, kp_image );
    extractor.compute( image, kp_image, des_image );


    matcher.knnMatch(des_object, des_image, matches, 2);



    for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
    {
        if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
        {
            good_matches.push_back(matches[i][0]);
        }
    }

        //Draw only "good" matches

    drawMatches( object, kp_object, image, kp_image, good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

    if (good_matches.size() >= 4)
    {
        printf("Images matching %d , %d", good_matches.size(), kp_object.size());

        //return 1;

        for( int i = 0; i < good_matches.size(); i++ )
        {

            //Get the keypoints from the good matches

            obj.push_back( kp_object[ good_matches[i].queryIdx ].pt );
            scene.push_back( kp_image[ good_matches[i].trainIdx ].pt );
        }

        //H = findHomography( obj, scene, CV_RANSAC );
        //printf("Size : %d", H.size());
        //perspectiveTransform( obj_corners, scene_corners, H);
        //printf("Size : %d --- %d --- %d", H.size(), scene_corners.size()); 

    }else{

        printf("Images matching %d , %d", good_matches.size(), kp_object.size());
    }

        //Show detected matches

    imshow( "Good Matches", img_matches );
    waitKey(0);
    return 0;

In this code i want to know what exactly happens through this method

matcher.knnMatch(des_object, des_image, matches, 2);

As i know i passes the two descriptors of the matching images and the matches vector is filled with 2 nearest neighbors. I want to know what exactly happens in the method and how the matches method is filled and what points are filled to it.

In this code segment

for(int i = 0; i < min(des_image.rows-1,(int) matches.size()); i++) //THIS LOOP IS SENSITIVE TO SEGFAULTS
    {
        if((matches[i][0].distance < 0.6*(matches[i][1].distance)) && ((int) matches[i].size()<=2 && (int) matches[i].size()>0))
        {
            good_matches.push_back(matches[i][0]);
        }
    }

im using the nearest neibour distance ratio(nndr) as 0.6, i wanted to know how the good_matches are find out and how the nndr value change will effect.

It would be a great help, if i could resolve this code. Thanks.

Upvotes: 1

Views: 804

Answers (1)

scap3y
scap3y

Reputation: 1198

The FlannBasedMatcher is based on the paper written by Muja et. al.; you can find the exact algorithm and how they go about it there..

Regarding the good_matches, you just saw in the code snippet itself that it is a collection of the best matches your result has based on the criteria, i.e., nndr.. It is basically a threshold that decides how far a match is allowed before dropping the match altogether.. Higher the threshold, more points are considered and more are the number of positive matches (whether they are true positives or not will be determined by your dataset and the way you have set the nndr level)..

Hope this helps.

Upvotes: 3

Related Questions