Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Partial Matches using FLANN Based Matcher. How to increase leniancy? c++

Hi!

I am currently trying to use opencv's FLANN Based Matcher using SURF detectors to try match a template in a scene. However the template is showing the image from a different rotation, scale and perspective. So far the code has been successful at finding some matches but not enough for a bounding box to be drawn around the template in the scene (Using findHomography() and perspectiveTransform()).

The objects of interest are birds in flight and as such are ever changing. What I want to achieve is to have a bounding box drawn around the object of interest in the scene when as little as 2 "good matches" are found.

Any and all help would be greatly appreciated!

Thanks, Levi.

code excerpt screenshots attached as .JPG 's : image description image description image description

click to hide/show revision 2
None

updated 2017-10-04 06:23:46 -0500

berak gravatar image

Partial Matches using FLANN Based Matcher. How to increase leniancy? c++

Hi!

I am currently trying to use opencv's FLANN Based Matcher using SURF detectors to try match a template in a scene. However the template is showing the image from a different rotation, scale and perspective. So far the code has been successful at finding some matches but not enough for a bounding box to be drawn around the template in the scene (Using findHomography() and perspectiveTransform()).

The objects of interest are birds in flight and as such are ever changing. What I want to achieve is to have a bounding box drawn around the object of interest in the scene when as little as 2 "good matches" are found.

Any and all help would be greatly appreciated!

Thanks, Levi.

code excerpt screenshots attached as .JPG 's : image description image description image description

Partial Matches using FLANN Based Matcher. How to increase leniancy? c++

Hi!

I am currently trying to use opencv's FLANN Based Matcher using SURF detectors to try match a template in a scene. However the template is showing the image from a different rotation, scale and perspective. So far the code has been successful at finding some matches but not enough for a bounding box to be drawn around the template in the scene (Using findHomography() and perspectiveTransform()).

The objects of interest are birds in flight and as such are ever changing. What I want to achieve is to have a bounding box drawn around the object of interest in the scene when as little as 2 "good matches" are found.

Any and all help would be greatly appreciated!

Thanks, Levi.

The code for this matching function is included below:

Mat Homography(Mat tmpl, Mat scene)
{
    cvtColor(scene,scene,COLOR_BGR2GRAY);
    cvtColor(tmpl,tmpl,COLOR_BGR2GRAY);
    Mat img_matches;

    //Detect the keypoints and extract descriptors (feature vectors) using SURF
    int minHessian = 400;

 Ptr<SURF> detector = SURF::create( minHessian );

vector<KeyPoint> keypoints_tmpl, keypoints_scene;
    Mat descriptors_tmpl, descriptors_scene;

    detector->detectAndCompute(tmpl, Mat(), keypoints_tmpl, descriptors_tmpl );
    detector->detectAndCompute(scene, Mat(), keypoints_scene, descriptors_scene );

    //Matching descriptor vectors using FLANN matcher
    if ( descriptors_tmpl.empty() )
        {
        //cvError(0,"MatchFinder","1st descriptor empty",__FILE__,__LINE__);
        return frame;
        }
    if ( descriptors_scene.empty() )
        {
        //cvError(0,"MatchFinder","2nd descriptor empty",__FILE__,__LINE__);
        return frame;
        }
    FlannBasedMatcher matcher;
    vector< DMatch > matches;
    matcher.match( descriptors_tmpl, descriptors_scene, matches );


    double max_dist = 0; double min_dist = 100;

    //max and min distances between keypoints
    for( int i = 0; i < descriptors_tmpl.rows; i++ )
    {
        double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    //Finds "good" matches (distance less than 3*min_dist )
    vector< DMatch > good_matches;

    for( int i = 0; i < descriptors_tmpl.rows; i++ )
    {
        if( matches[i].distance < 3*min_dist )
        {
                good_matches.push_back( matches[i]);
        }
    }


drawMatches( tmpl, keypoints_tmpl, scene, keypoints_scene,
               good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
               vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

    //Localize the tmpl
vector<Point2f> templ;
vector<Point2f> scn;

for( int i = 0; i < good_matches.size(); i++ )
{
    //keypoints from the good matches
    templ.push_back( keypoints_tmpl[ good_matches[i].queryIdx ].pt );
    scn.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
}

Mat H = findHomography( templ, scn, RANSAC );

//corners from the template ( the object to be "detected" )
vector<Point2f> tmpl_corners(4);
tmpl_corners[0] = cvPoint(0,0);
tmpl_corners[1] = cvPoint( tmpl.cols, 0 );
tmpl_corners[2] = cvPoint( tmpl.cols, tmpl.rows );
tmpl_corners[3] = cvPoint( 0, tmpl.rows );
vector<Point2f> scene_corners(4);

if(!H.empty())
{
        perspectiveTransform( tmpl_corners, scene_corners, H);
}  
//-- Draw lines between the corners (bounding box)
line( img_matches, scene_corners[0] + Point2f( tmpl.cols, 0), scene_corners[1] + Point2f( tmpl.cols, 0), Scalar(0, 255, 0), 4 );
line( img_matches, scene_corners[1] + Point2f( tmpl.cols, 0), scene_corners[2] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );
line( img_matches, scene_corners[2] + Point2f( tmpl.cols, 0), scene_corners[3] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );
line( img_matches, scene_corners[3] + Point2f( tmpl.cols, 0), scene_corners[0] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );

return img_matches;

}

Partial Matches using FLANN Based Matcher. How to increase leniancy? c++

Hi!

I am currently trying to use opencv's FLANN Based Matcher using SURF detectors to try match a template in a scene. However the template is showing the image from a different rotation, scale and perspective. So far the code has been successful at finding some matches but not enough for a bounding box to be drawn around the template in the scene (Using findHomography() and perspectiveTransform()).

The objects of interest are birds in flight and as such are ever changing. What I want to achieve is to have a bounding box drawn around the object of interest in the scene when as little as 2 "good matches" are found.

Any and all help would be greatly appreciated!

Thanks, Levi.

The code for this matching function is included below:

Mat Homography(Mat tmpl, Mat scene)
{
    cvtColor(scene,scene,COLOR_BGR2GRAY);
    cvtColor(tmpl,tmpl,COLOR_BGR2GRAY);
    Mat img_matches;

    //Detect the keypoints and extract descriptors (feature vectors) using SURF
    int minHessian = 400;

  Ptr<SURF> detector = SURF::create( minHessian );

 vector<KeyPoint> keypoints_tmpl, keypoints_scene;
    Mat descriptors_tmpl, descriptors_scene;

    detector->detectAndCompute(tmpl, Mat(), keypoints_tmpl, descriptors_tmpl );
    detector->detectAndCompute(scene, Mat(), keypoints_scene, descriptors_scene );

    //Matching descriptor vectors using FLANN matcher
    if ( descriptors_tmpl.empty() )
     {
        //cvError(0,"MatchFinder","1st descriptor empty",__FILE__,__LINE__);
        return frame;
     }
    if ( descriptors_scene.empty() )
     {
        //cvError(0,"MatchFinder","2nd descriptor empty",__FILE__,__LINE__);
        return frame;
     }
     FlannBasedMatcher matcher;
    vector< DMatch > matches;
    matcher.match( descriptors_tmpl, descriptors_scene, matches );
 
    double max_dist = 0; double min_dist = 100;

    //max and min distances between keypoints
    for( int i = 0; i < descriptors_tmpl.rows; i++ )
    {
        double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    //Finds "good" matches (distance less than 3*min_dist )
    vector< DMatch > good_matches;

    for( int i = 0; i < descriptors_tmpl.rows; i++ )
    {
        if( matches[i].distance < 3*min_dist )
        {
                good_matches.push_back( matches[i]);
        }
    }

  drawMatches( tmpl, keypoints_tmpl, scene, keypoints_scene,
                good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
                vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );

    //Localize the tmpl
 vector<Point2f> templ;
 vector<Point2f> scn;

 for( int i = 0; i < good_matches.size(); i++ )
 {
     //keypoints from the good matches
     templ.push_back( keypoints_tmpl[ good_matches[i].queryIdx ].pt );
     scn.push_back( keypoints_scene[ good_matches[i].trainIdx ].pt );
 }

 Mat H = findHomography( templ, scn, RANSAC );

 //corners from the template ( the object to be "detected" )
 vector<Point2f> tmpl_corners(4);
 tmpl_corners[0] = cvPoint(0,0);
 tmpl_corners[1] = cvPoint( tmpl.cols, 0 );
 tmpl_corners[2] = cvPoint( tmpl.cols, tmpl.rows );
 tmpl_corners[3] = cvPoint( 0, tmpl.rows );
 vector<Point2f> scene_corners(4);

 if(!H.empty())
 {
        perspectiveTransform( tmpl_corners, scene_corners, H);
 }  
 //-- Draw lines between the corners (bounding box)
 line( img_matches, scene_corners[0] + Point2f( tmpl.cols, 0), scene_corners[1] + Point2f( tmpl.cols, 0), Scalar(0, 255, 0), 4 );
 line( img_matches, scene_corners[1] + Point2f( tmpl.cols, 0), scene_corners[2] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );
 line( img_matches, scene_corners[2] + Point2f( tmpl.cols, 0), scene_corners[3] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );
 line( img_matches, scene_corners[3] + Point2f( tmpl.cols, 0), scene_corners[0] + Point2f( tmpl.cols, 0), Scalar( 0, 255, 0), 4 );

 return img_matches;
}

}