OpenCV绘制匹配点时出现错误

6

我的代码包括一个部分,其中我会对一组匹配进行排序,并根据距离定义好的匹配项。当我尝试绘制这些匹配项时,出现了错误:

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文件显示:

// 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 );
     }
}

我的drawMatches调用如下:

Mat matchesImage;

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

有人能帮我解释一下这个错误吗?

更新:

这是我的good_matches计算代码:

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 );

更新2:

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

你使用什么函数来计算good_matches变量? - Marcin Kolny
我已经在更新2中添加了我的匹配器代码。 - P3d0r
如果您将“matches”(而不是“good_matches”)提供给drawMatches函数,它是否有效? - Ha Dang
1
我可能看到了你的错误。你知道以下关系吗:descriptors1.rows >= matches.size()? - Marcin Kolny
1
应该是 drawMatches(im2,keypoints2,im1,keypoints1, - aronp
显示剩余7条评论
4个回答

4
问题与您匹配点的顺序有关。如果您这样做,例如:
match(right_desc, left_desc)

drawMatches函数必须按照相同的顺序进行操作。这将起作用(考虑我的匹配示例):

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

这会产生以下错误:
drawMatches(left_rgb, left_pts, right_rgb, right_pts, matches)

顺序还会影响匹配点的查询和训练 (即queryIdxtrainIdx),当您访问匹配项的坐标时。请注意,right_ptsleft_pts分别由right_descleft_desc描述。

希望能对某些人有所帮助。


2

我认为你应该在每次迭代中使用 good_matches.clear() 命令清除 good_matches 向量的内容(如果您使用 while(1) 循环从相机获取帧,您需要在 while(1) 循环后编写 good_matches.clear() 命令):

while(1) {
     good_matches.clear();
     // other code ...
}

0

一般来说,good_matches 是一个数组,将 keypoints1 和 keypoints2 数组中的点绑定在一起。因此,点 keypoints1[good_matches[m].queryIdx] 对应于点 keypoints2[good_matches[m].trainIdx]。 正如您所看到的,在 OpenCV 代码中进行断言是有意义的。

看起来问题在于 matches 数组。


0

我不同意上面的答案。

你传递给 matcher.match(dscp1, dscp2, matches)drawMatch(img1, kp1, img2, kp2, good_matches) 的参数是相应的(它们都匹配来自 keypoints2 的每个描述符中的 keypoints1keypoints1 被称为查询集,而 keypoints2 被称为训练集)。

错误可能是由你传递给 drawMatch() 的错误的 keypoints1keypoints2 导致的。检查 good_matches 中的索引是否与 keypoints1 中的 kp 对应。(如果在选择好的匹配时减少了 keypoints 的数量,可能会发生这种情况。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接