Вы можете увидеть код matchers here
Поезд дескриптор Сличитель (например, flann index). Во всех методах для сопоставления метод train() запускается каждый раз перед сопоставлением.
Да, как вы можете видеть из кода, в соответствующих функциях вызывается train()
.
void DescriptorMatcher::knnMatch(InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int knn,
InputArrayOfArrays masks, bool compactResult)
{
if(empty() || queryDescriptors.empty())
return;
CV_Assert(knn > 0);
checkMasks(masks, queryDescriptors.size().height);
train();
knnMatchImpl(queryDescriptors, matches, knn, masks, compactResult);
}
void DescriptorMatcher::radiusMatch(InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
InputArrayOfArrays masks, bool compactResult)
{
matches.clear();
if(empty() || queryDescriptors.empty())
return;
CV_Assert(maxDistance > std::numeric_limits<float>::epsilon());
checkMasks(masks, queryDescriptors.size().height);
train();
radiusMatchImpl(queryDescriptors, matches, maxDistance, masks, compactResult);
}
При вызове match()
, он будет вызывать в самом деле knnMatch
с knn = 1
void DescriptorMatcher::match(InputArray queryDescriptors, std::vector<DMatch>& matches, InputArrayOfArrays masks)
{
std::vector<std::vector<DMatch> > knnMatches;
knnMatch(queryDescriptors, knnMatches, 1, masks, true /*compactResult*/);
convertMatches(knnMatches, matches);
}
Базовая реализация train()
делает ничего:
void DescriptorMatcher::train()
{}
Только FlannBasedMatcher
перегрузки train()
:
void FlannBasedMatcher::train()
{
if(!flannIndex || mergedDescriptors.size() < addedDescCount)
{
// FIXIT: Workaround for 'utrainDescCollection' issue (PR #2142)
if (!utrainDescCollection.empty())
{
CV_Assert(trainDescCollection.size() == 0);
for (size_t i = 0; i < utrainDescCollection.size(); ++i)
trainDescCollection.push_back(utrainDescCollection[i].getMat(ACCESS_READ));
}
mergedDescriptors.set(trainDescCollection);
flannIndex = makePtr<flann::Index>(mergedDescriptors.getDescriptors(), *indexParams);
}
}
Для примера о том, как использовать FlannBasedMatcher
вы можете обратиться к OpenCV doc example
Вы можете обратиться к этой answer, чтобы знать, что делается на этапе подготовки. Короче говоря, вы строите индекс для сопряжения. Вы найдете исходный код here