以下代码是用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-tree)。但是如果我们看一下train()函数,这里就是捕获:
void FlannBasedMatcher::train()
{
if( flannIndex.empty() || mergedDescriptors.size() < addedDescCount )
{
mergedDescriptors.set( trainDescCollection );
flannIndex = new flann::Index( mergedDescriptors.getDescriptors(), *indexParams );
}
}
这两个操作(设置训练描述符和flann索引,我在调用train()之前已经完成)。那么什么时候构建kd树呢?
答案 0 :(得分:3)
当代码调用FlannBasedMatcher :: train()时,FlannBasedMatcher的索引将由
构建flannIndex = new flann::Index( mergedDescriptors.getDescriptors(), *indexParams );
代码
if( flannIndex.empty() || mergedDescriptors.size() < addedDescCount )
是检查之前是否已经构建了FlannBasedMatcher的索引。如果之前构建了索引,train()函数将跳过构建索引的过程以节省时间。
答案 1 :(得分:2)
从the documentation开始,每次匹配前都会进行训练(即在你的汽车建造kd树中)。
cv::DescriptorMatcher
类在需要时自动调用训练方法。