OpenCV drawMatches error

10,109

Solution 1

In general, good_matches is an array, which binds points from both keypoints1 and keypoints2 array. So point keypoints1[good_matches[m].queryIdx] corresponds to point keypoints2[good_matches[m].trainIdx]. As you can see, assertions in opencv code have sense.

It seems, the problem is in matches array.

Solution 2

The problem has to do with the order you matched the points. If you did, e.g.:

match(right_desc, left_desc)

function drawMatches will have to follow the same order. This will work (considering my matching example):

drawMatches(right_rgb, right_pts, left_rgb, left_pts, matches)

this will produce the error you have:

drawMatches(left_rgb, left_pts, right_rgb, right_pts, matches)

The order will also affect what is query and what is train (i.e. queryIdx and trainIdx), when you access the coordinates of the matches. Note that right_pts and left_pts are the keypoints described by right_desc and left_desc respectively.

Hope it helps someone.

Solution 3

I think you should clear the contents of the good_matches vector with the good_matches.clear() command for each iteration (if you use while(1) loop for get frame from camera, you will write good_matches.clear() command after while(1) loop:

while(1) {
     good_matches.clear();
     // other code ...
}
Share:
10,109
P3d0r
Author by

P3d0r

Updated on June 14, 2022

Comments

  • P3d0r
    P3d0r almost 2 years

    My code consists of a section where I sort through a set of matches and define good matches based on distance. When I try to drawMatches, I receive an error:

    OpenCV Error: Assertion failed (i1 >= 0 && i1 < static_cast<int>(keypoints1.size())) in drawMatches, file /home/user/OpenCV/opencv-2.4.10/modules/features2d/src/draw.cpp, line 207
    terminate called after throwing an instance of 'cv::Exception'
      what():  /home/user/OpenCV/opencv-2.4.10/modules/features2d/src/draw.cpp:207: error: (-215) i1 >= 0 && i1 < static_cast<int>(keypoints1.size()) in function drawMatches
    

    draw.cpp file shows:

    // draw matches
    for( size_t m = 0; m < matches1to2.size(); m++ )
    {
         if( matchesMask.empty() || matchesMask[m] )
         {
              int i1 = matches1to2[m].queryIdx;
              int i2 = matches1to2[m].trainIdx;
              CV_Assert(i1 >= 0 && i1 < static_cast<int>(keypoints1.size()));
              CV_Assert(i2 >= 0 && i2 < static_cast<int>(keypoints2.size()));
              const KeyPoint &kp1 = keypoints1[i1], &kp2 = keypoints2[i2];
              _drawMatch( outImg, outImg1, outImg2, kp1, kp2, matchColor, flags );
         }
    }
    

    My drawMatches call follows:

    Mat matchesImage;
    
    drawMatches( im1, keypoints1, im2, keypoints2,
        good_matches, matchesImage, Scalar::all(-1), Scalar::all(-1),
        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
    

    Can anybody help explain this error to me?

    Update:

    Here is my code for the good_matches calculation

    double min_dist = 10000;
    double max_dist = 0;
    
    //-- Quick calculation of max and min distances between keypoints
    for( int i = 0; i < descriptors1.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
    std::vector< DMatch > good_matches;
    
    for( int i = 0; i < descriptors1.rows; i++ ) {
        if( matches[i].distance <= max(2*min_dist, 0.02) ) { 
            good_matches.push_back( matches[i]); 
        }
    }
    
    for( int i = 0; i < (int)good_matches.size(); i++ ) {
        printf( "-- Good Match [%d] Keypoint 1: %d  -- Keypoint 2: %d  \n", 
            i, good_matches[i].queryIdx, good_matches[i].trainIdx ); 
    }
    
    cout << "number of good matches: " << (int)good_matches.size() << endl;;
    
    //Draw matches and save file
    Mat matchesImage;
    
    drawMatches( im1, keypoints1, im2, keypoints2,
        good_matches, matchesImage, Scalar::all(-1), Scalar::all(-1),
        vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
    

    Update 2:

    BFMatcher matcher(NORM_L2, true);
    vector<DMatch> matches;
    matcher.match(descriptors1, descriptors2, matches);