OpenCV drawMatches error
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 ...
}
P3d0r
Updated on June 14, 2022Comments
-
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);