这是OpenCV的drawMatches()
功能:
void drawMatches(Mat img1, vector<KeyPoint> keypoints1,
Mat img2, vector<KeyPoint> keypoints2,
vector<DMatch> matches,
Mat outImg) //want keypoints1[i] = keypoints2[matches[i]]
请注意,匹配的类型为vector< DMatch>.这是DMatch
构造函数:
DMatch(int queryIdx, int trainIdx, float distance)
据推测,queryIdx是一组关键点的索引,trainIdx是另一组关键点的索引.
问题:queryIdx索引到keypoints1并且trainIdx索引到keypoints2是真的吗?或者是周围的其他方式?
这取决于你如何获得比赛.
如果您按顺序调用匹配函数:
match(descriptor_for_keypoints1, descriptor_for_keypoints2, matches)
然后queryIdx指的是keypoints1,trainIdx指的是keypoints2,反之亦然.
我在features2d框架中使用不同的检测器从连续两个得到了特征点:
在第一帧中,特征点以红色绘制
在下一帧中,要素点以蓝色绘制
我想在第一帧(红点图像)内的这些红色和蓝色(匹配)点之间画一条线. opencv中的drawmatches函数没有帮助,因为它显示了一个窗口,其中两个连续的帧彼此相邻以进行匹配.在OpenCV中有可能吗?
我想你想要想象每个关键点如何在两帧之间移动.据我所知,OpenCV中没有内置功能可以满足您的要求.
但是,正如您调用了drawMatches()函数,您已经拥有两个关键点集(以C代码为例)vector< KeyPoint>& keypoints1,keypoints2和匹配向量< DMatch>& matches1to2.然后,您可以从Point keypoints1.pt获取每个关键点的像素坐标,并通过调用line()函数在关键点之间绘制线条.您应该小心,因为您想在第一帧中绘制关键点2,像素坐标可能超过img1的大小.
特征点匹配及消除误匹配点
matches1to2 | Matches from the first image to the second one, which means that keypoints1[i] has a corresponding point in keypoints2[matches[i]] . |
Mastering OpenCV with Practical Computer Vision Projects 中的第三章里面讲到了几种特征点匹配的优化方式
1. OpenCV提供了两种Matching方式:
• Brute-force matcher (cv::BFMatcher)
• Flann-based matcher (cv::FlannBasedMatcher)
Brute-force matcher就是用暴力方法找到点集一中每个descriptor在点集二中距离最近的descriptor;
Flann-based matcher 使用快速近似最近邻搜索算法寻找(用快速的第三方库近似最近邻搜索算法)
一般把点集一称为 train set (训练集)对应模板图像,点集二称为 query set(查询集)对应查找模板图的目标图像。
为了提高检测速度,你可以调用matching函数前,先训练一个matcher。训练过程可以首先使用cv::F