训练具体在哪个阶段在OpenCV的FlannBasedMatcher进行

At what stage the training exactly takes place in FlannBasedMatcher in OpenCV?

本文关键字:OpenCV 进行 FlannBasedMatcher      更新时间:2023-10-16

下面的代码是用C++编写的,我正在使用OpenCV进行实验。假设我以以下方式使用kd-tree(FlannBasedMatcher):

//these are inputs to the code snippet below. 
//They are filled with suitable values
Mat& queryDescriptors;
vector<Training> &trainCollection;
vector< vector<DMatch> >& matches;
int knn;
//setting flann parameters
const Ptr<flann::IndexParams>& indexParams=new flann::KDTreeIndexParams(4);
const Ptr<flann::SearchParams>& searchParams=new flann::SearchParams(64);
FlannBasedMatcher matcher(indexParams, searchParams);
for (int i = 0; i < trainCollection.size();i++){
    Training train = trainCollection.at(i);  
    Mat trainDescriptors(train.trainDescriptors);
    trainDescriptorCollection.push_back(trainDescriptors);
}
matcher.add(trainDescriptorCollection);
matcher.train();
//Now, we may do knnMatch (or anyother matching) 
matcher.knnMatch(queryDescriptors,matches,knn);

在上面的代码中,似乎在调用train()函数时进行了训练(即构建了kd树)。但如果我们看看train()函数内部,就会发现问题:

void FlannBasedMatcher::train()
{
    if( flannIndex.empty() || mergedDescriptors.size() < addedDescCount )
    {
        mergedDescriptors.set( trainDescCollection );
        flannIndex = new flann::Index( mergedDescriptors.getDescriptors(), *indexParams );
    }
}

这两个操作(设置训练描述符和flann索引,我在调用train()之前已经做过了)。那么kd树究竟是什么时候建立的呢?

当代码调用FlannBasedMatcher::train()时,FlannBasetMatcher的索引将由构建

flannIndex = new flann::Index( mergedDescriptors.getDescriptors(), *indexParams );

代码

if( flannIndex.empty() || mergedDescriptors.size() < addedDescCount )

是为了检查FlannBasedMatcher的索引以前是否已经构建过。如果之前已经建立了索引,train()函数将跳过建立索引的过程以节省时间。

根据文档,每次匹配之前都要进行训练(即在构建kd树的cae中)。cv::DescriptorMatcher类在需要时自动调用训练方法。