Reputation: 1099
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);
Upvotes: 6
Views: 13614
Reputation: 1
I don't agree with answers above.
Parameters you pass into matcher.match(dscp1, dscp2, matches)
and drawMatch(img1, kp1, img2, kp2, good_matches)
are corresponding (they are both matching every descriptor in keypoints1
from keypoints2
, keypoints1
is called query set while keypoints2
is called train set.)
The error might be caused by the wrong keypoints1
and keypoints2
you pass into drawMatch()
. Check whether the index in good_matches
correspond with kp in keypoints1
. (If you reduce the number of keypoints
while picking good matches, this occasion could happen.)
Upvotes: 0
Reputation: 1178
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.
Upvotes: 5
Reputation: 48
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 ...
}
Upvotes: 2
Reputation: 633
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.
Upvotes: 0