queryIdx : 查询点的索引(当前要寻找匹配结果的点在它所在图片上的索引).
trainIdx : 被查询到的点的索引(存储库中的点的在存储库上的索引)
imgIdx : 有争议(常为0)
DMatch的定义
/*
* Struct for matching: query descriptor index, train descriptor index, train image index and distance between descriptors.
*/
struct CV_EXPORTS_W_SIMPLE DMatch
{
CV_WRAP DMatch() : queryIdx(-1), trainIdx(-1), imgIdx(-1), distance(FLT_MAX) {}
CV_WRAP DMatch( int _queryIdx, int _trainIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(-1), distance(_distance) {}
CV_WRAP DMatch( int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx(_trainIdx), imgIdx(_imgIdx), distance(_distance) {}
CV_PROP_RW int queryIdx; // query descriptor index
CV_PROP_RW int trainIdx; // train descriptor index
CV_PROP_RW int imgIdx; // train image index
CV_PROP_RW float distance;
// less is better
bool operator<( const DMatch &m ) const
{
return distance < m.distance;
}
};
具体解释,验证过程
我们从图1中提取了 sift/surf/orb或其他种类的特征点vector<KeyPoint> keypoints_1
以及相应的描述子descriptor1
,大小为319,从图2中也提取了特征点vector<KeyPoint> keypoints_2
以及相应的描述子descriptor2
,大小为320.
//descriptor1
中的每一个特征点的描述子称为 d1i
,descriptor2
中的每一个特征点的描述子称为 d2i
.
//通过opencv的`FlannBasedMatcher`或者`BruteForceMatcher<>`进行匹配,
// 在descriptor2中挑选两个离 `d1i`最近的描述子放入matches之中。
FlannBasedMatcher matcher;
std::vector<vector<DMatch>> matches;
matcher.knnMatch(descriptor1,descriptor2,matches,2);
通过调试得到如图所示结果:
可以看出 queryIdx是按顺序增大的, 相应的trainIdx是不断跳变的,且imgIdx一直是0.
可以从matches[0]看出,这里的queryIdx是指第0张图的第0个特征点匹配到了第1张图的第6个特征点(距离最近),同时第0张图的第0个特征点匹配到了第1张图的第128个特征点(距离第2近)。
于是 queryIdx 是你想要为“它”找到匹配结果的“它”的索引。 trainIdx是 “它”的匹配结果的索引。
由于imgIdx一直是0,只能说在这里可能没什么用。有些文章说 imgIdx指的是第0张图,有的说是第1张图的意思,从这里感觉更应该是指第0张图。