0

我正在使用 Opancv4android 进行实时对象识别,我能够使用 ORB 检测器和描述符提取器从我使用相机捕获的图像中检测、提取特征点。现在,我想构建一个 Kdtree 并用这些特征点训练它们,然后我将树中的这些特征点与相机实时检测到的特征点进行匹配并识别对象。请帮助我了解如何在 opencv 中构建 KD 树或 KDtree 上用于 opencv 的任何指针或参考/教程将非常有帮助。

4

2 回答 2

3

实现方法,完成后将发布代码

收集训练集

捕获所有要训练的图像并将它们存储在 android 的 SDcard/external 目录中,并有一个 xml/txt 文件,其中包含您捕获的图像的所有名称。

特征提取

从相机捕获帧并将其传递给 Mat 对象,您可以从那里提取特征以获取查询描述符集。为了从训练集中提取特征,您从存储位置读取文件,获取文件中的图像列表,并将存储的所有图像传递到 Mat 对象的向量中,然后提取特征点以获得训练描述符集。

描述符匹配

这里也是如此,您需要传递查询描述符和训练描述符的向量,并在获得正确匹配的结果后以 Dmatches 的向量形式获得输出,您可以在图像之间绘制匹配或使用单应性在已识别的矩形上绘制矩形目的。

骨架代码

static void detectKeypoints( const Mat& queryImage, vector<KeyPoint>& queryKeypoints,
                  const vector<Mat>& trainImages, vector<vector<KeyPoint> >& trainKeypoints,
                  Ptr<FeatureDetector>& featureDetector )
{

featureDetector->detect( queryImage, queryKeypoints );
featureDetector->detect( trainImages, trainKeypoints );

}

static void computeDescriptors( const Mat& queryImage, vector<KeyPoint>& queryKeypoints, Mat& queryDescriptors,
                     const vector<Mat>& trainImages, vector<vector<KeyPoint> >& trainKeypoints, vector<Mat>& trainDescriptors,
                     Ptr<DescriptorExtractor>& descriptorExtractor )
{

descriptorExtractor->compute( queryImage, queryKeypoints, queryDescriptors );
descriptorExtractor->compute( trainImages, trainKeypoints, trainDescriptors );


}

static void matchDescriptors( const Mat& queryDescriptors, const vector<Mat>& trainDescriptors,
                   vector<DMatch>& matches, Ptr<DescriptorMatcher>& descriptorMatcher )
{

descriptorMatcher->add( trainDescriptors );
descriptorMatcher->train();

descriptorMatcher->match( queryDescriptors, matches );

CV_Assert( queryDescriptors.rows == (int)matches.size() || matches.empty() );


}
于 2013-11-15T16:09:55.160 回答
2

FLANN 匹配器 (也是这个链接)基于 kd-tree,它是在匹配器内部自动构建的。

但我建议您使用带有汉明距离的 BFMatcher - 它是为您的情况下的 ORB 二进制描述符而设计的。这是一个如何用于 FREAK 的示例(也是二进制描述符)。

于 2013-11-14T18:19:19.600 回答