我通过在features2d框架中使用不同的探测器连续两次得到了特征点:
在第一帧中,要素点以红色绘制
在下一帧中,要素点以蓝色绘制
我想在第一帧内的红色和蓝色(匹配)点之间画一条线(带红点的图像)。 opencv中的 drawmatches 功能无效,因为它显示了一个窗口,其中两个连续的帧彼此相邻以进行匹配。在OpenCV中有可能吗?
提前致谢
答案 0 :(得分:2)
我想你想要想象每个关键点在两帧之间的移动方式。据我所知,OpenCV中没有内置功能可以满足您的要求。
但是,正如您调用drawMatches()
函数一样,您已经拥有两个关键点集(以C ++代码为例)vector<KeyPoint>& keypoints1, keypoints2
和匹配vector<DMatch>& matches1to2
。然后,您可以从Point keypoints1.pt
获取每个关键点的像素坐标,并通过调用line()
函数在关键点之间绘制线条。
您应该小心,因为您想在第一帧中绘制keypoints2
,因此像素坐标可能超过img1
的大小。
有一种快速了解关键点运动的方法。以下是Matlab中imshowpair()
显示的结果:
答案 1 :(得分:1)
在找到好的匹配后,我使用此代码绘制线条。
(...some code...)
//draw good matches
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 );
//query image is the first frame
Point2f point_old = keypoints_1[good_matches[i].queryIdx].pt;
//train image is the next frame that we want to find matched keypoints
Point2f point_new = keypoints_2[good_matches[i].trainIdx].pt;
//keypoint color for frame 1: RED
circle(img_1, point_old, 3, Scalar(0, 0, 255), 1);
circle(img_2, point_old, 3, Scalar(0, 0, 255), 1);
//keypoint color for frame 2: BLUE
circle(img_1, point_new, 3, Scalar(255, 0, 0), 1);
circle(img_2, point_new, 3, Scalar(255, 0, 0), 1);
//draw a line between keypoints
line(img_1, point_old, point_new, Scalar(0, 255, 0), 2, 8, 0);
line(img_2, point_old, point_new, Scalar(0, 255, 0), 2, 8, 0);
}
imwrite("directory/image1.jpg",img_1);
imwrite("directory/image2.jpg",img_2);
(...some code...)
我将结果保存到第一个(img_1)和下一个帧(img_2)。如您所见,我有不同的结果,但线条形状相同。在OpenCV的视频单应性样本中,关键点跟踪似乎是准确的。他们遵循这种方法:检测关键点 - &gt;计算关键点 - &gt; warp关键点 - &gt;匹配 - &GT;找到单应性 - &gt;绘制匹配。但是,我应用检测关键点 - &gt;计算关键点 - &gt;匹配 - &gt;绘制匹配。 如果我必须考虑单应性和透视(或其他东西)来准确地看到关键点运动,我会感到困惑。
第一帧的结果(img_1)
和下一帧(img_2)