首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用opencv flann::Index?

如何使用opencv flann::Index?
EN

Stack Overflow用户
提问于 2012-04-26 23:27:58
回答 2查看 20.5K关注 0票数 11

我对opencv flann::Index有一些问题-

我正在创建索引

代码语言:javascript
复制
    Mat samples = Mat::zeros(vfv_net_quie.size(),24,CV_32F);
        for (int i =0; i < vfv_net_quie.size();i++)
        {
           for (int j = 0;j<24;j++)
           {
              samples.at<float>(i,j)=(float)vfv_net_quie[i].vfv[j];
           }
        }
    cv::flann::Index flann_index(
            samples,
            cv::flann::KDTreeIndexParams(4),
            cvflann::FLANN_DIST_EUCLIDEAN
               );
    flann_index.save("c:\\index.fln");

之后,我试着装上它,找到最近的邻居

代码语言:javascript
复制
cv::flann::Index flann_index(Mat(),
    cv::flann::SavedIndexParams("c:\\index.fln"),
    cvflann::FLANN_DIST_EUCLIDEAN
    );

cv::Mat resps(vfv_reg_quie.size(), K, CV_32F);
cv::Mat nresps(vfv_reg_quie.size(), K, CV_32S);
cv::Mat dists(vfv_reg_quie.size(), K, CV_32F);

flann_index.knnSearch(sample,nresps,dists,K,cv::flann::SearchParams(64));

并在miniflann.cpp中设置访问冲突

代码语言:javascript
复制
((IndexType*)index)->knnSearch(_query, _indices, _dists, knn,
                          (const ::cvflann::SearchParams&)get_params(params));

请帮帮忙

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-11 01:39:33

您不应该将flann file加载到Mat()中,因为它是存储索引的位置。它是在调用构造函数后销毁的临时对象。这就是为什么调用knnSearch()时索引没有指向任何有用的地方的原因。

我尝试了以下几点:

代码语言:javascript
复制
cv::Mat indexMat;
cv::flann::Index flann_index(
    indexMat,
    cv::flann::SavedIndexParams("c:\\index.fln"),
    cvflann::FLANN_DIST_EUCLIDEAN
);

结果是:

代码语言:javascript
复制
Reading FLANN index error: the saved data size (100, 64) or type (5) is different from the passed one (0, 0), 0

这意味着矩阵必须用正确的维度初始化(在我看来非常愚蠢,因为我不一定知道有多少元素存储在我的索引中)。

代码语言:javascript
复制
cv::Mat indexMat(samples.size(), CV_32FC1);
cv::flann::Index flann_index(
    indexMat,
    cv::flann::SavedIndexParams("c:\\index.fln"),
    cvflann::FLANN_DIST_EUCLIDEAN
);

真的很管用。

票数 12
EN

Stack Overflow用户

发布于 2016-12-07 17:23:41

在公认的答案中,不清楚和误导为什么cv::flann::Index构造函数中的输入矩阵必须与用于生成保存的索引的矩阵具有相同的维度。我将通过一个例子详细说明@Sau的评论。

使用cv::Mat sample作为输入生成KDTreeIndex,然后保存。当您加载它时,您必须提供相同的sample矩阵来生成它,类似于(使用模板化的GenericIndex接口):

代码语言:javascript
复制
cv::Mat sample(sample_num, sample_size, ... /* other params */);
cv::flann::SavedIndexParams index_params("c:\\index.fln");
cv::flann::GenericIndex<cvflann::L2<float>> flann_index(sample, index_params);

L2是通常的欧几里德距离(其他类型可以在opencv2/flann/dist.h中找到)。

现在可以使用索引,如图所示查找query点的最近邻居:

代码语言:javascript
复制
std::vector<float> query(sample_size);
std::vector<int> indices(K);
std::vector<float> distances(K);

flann_index.knnSearch(query, indices, distances, K, cv::flann::SearchParams(64));

矩阵indices将包含矩阵 sample,中的最近邻居的索引位置,该矩阵最初用于生成索引。这就是为什么你需要用来生成索引的矩阵来加载保存的索引,否则返回的向量将包含指向无意义的“最近邻居”的索引。

此外,您还会得到一个distances矩阵,其中包含找到的邻居距离您的query点有多远,例如,稍后您可以使用该矩阵执行一些inverse distance weighting

还请注意,sample_size必须在sample矩阵和query点之间匹配。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10336568

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档