求解如下红色点的3个最近邻居

1、测试代码

int main() {//用于构造kdtree的点集vector<cv::Point2f> features = { { 1,1 },{ 2, 2},{ 3, 3},{ 4, 4},{ 2, 4} };cv::Mat source = cv::Mat(features).reshape(1);source.convertTo(source, CV_32F);cv::flann::KDTreeIndexParams indexParams(2);cv::flann::Index kdtree(source, indexParams); //预设knnSearch所需参数及容器int queryNum = 3;//用于设置返回邻近点的个数vector<float> vecQuery(2);//存放查询点的容器vector<int> vecIndex(queryNum);//存放返回的点索引vector<float> vecDist(queryNum);//存放距离cv::flann::SearchParams params(32);//设置knnSearch搜索参数//KD树knn查询vecQuery = { 3, 4};kdtree.knnSearch(vecQuery, vecIndex, vecDist, queryNum, params);cout << "vecDist: " << endl;for (auto&x : vecDist)cout << x << " ";cout << endl;cout << "vecIndex: " << endl;for (auto&x : vecIndex)cout << x << " ";return 0;
}

输出:
vecDist: (注意这里是距离的平方)
1 1 1
vecIndex:
2 3 4

2、可能的问题

我写程序需要构建多个kdtree, 我试图用vector存储多个kdtree,我写成如下的代码就会报错

int main(){vector<cv::flann::Index> kdtrees;vector<cv::Point2f> features = { { 1,1 },{ 2, 2 },{ 3, 3 },{ 4, 4 },{ 2, 4 } };cv::Mat source = cv::Mat(features).reshape(1);cout << source;source.convertTo(source, CV_32F);cv::flann::KDTreeIndexParams indexParams(2);cv::flann::Index kdtree(source, indexParams);kdtrees.push_back(kdtree);
}

报错为:

这里显示的应该是vector释放的时候出了问题,初步查明 cv::flann::Index 这个class有一个 指针类型:void* index. 很有可能是浅拷贝的时候,释放kdtree的时候将 index释放,然后在释放vector的是时候再次释放index出了问题。

protected:cvflann::flann_distance_t distType;cvflann::flann_algorithm_t algo;int featureType;void* index;

因此,这里直接改为指针形式即可。

int main(){vector<cv::flann::Index*> kdtrees;vector<cv::Point2f> features = { { 1,1 },{ 2, 2 },{ 3, 3 },{ 4, 4 },{ 2, 4 } };cv::Mat source = cv::Mat(features).reshape(1);cout << source;source.convertTo(source, CV_32F);cv::flann::KDTreeIndexParams indexParams(2);cv::flann::Index* pkdtree = new cv::flann::Index(source, indexParams);kdtrees.push_back(pkdtree);
}

3、knnsearch返回无穷大的值

当我写成如下形式的时候(注意kdtrees后面加了局部作用域)

int main() {int queryNum = 3;//用于设置返回邻近点的个数vector<float> vecQuery(2);//存放查询点的容器vector<int> vecIndex(queryNum);//存放返回的点索引vector<float> vecDist(queryNum);//存放距离cv::flann::SearchParams params(32);//设置knnSearch搜索参数cv::flann::KDTreeIndexParams indexParams(2);vecQuery[0] = 3, vecQuery[1] = 4;vector<cv::flann::Index*> kdtrees;{vector<cv::Vec2d> features = { { 1,1 },{ 2, 2 },{ 3, 3 },{ 4, 4 },{ 2, 4 } };cv::Mat source = cv::Mat(features).reshape(1);source.convertTo(source, CV_32F);cv::flann::Index* kdtree = new cv::flann::Index(source, indexParams);kdtrees.push_back(kdtree);}kdtrees[0]->knnSearch(vecQuery, vecIndex, vecDist, queryNum, params);for (int i = 0; i < vecIndex.size(); i++)cout << "nearest id: " << vecIndex[i] << "\tdist:" << vecDist[i] << endl;return 0;
}

输出结果为:

nearest id: 2 dist:7.98718e+36
nearest id: 3 dist:7.98718e+36
nearest id: 4 dist:7.98718e+36

为何是这么大的值?调查发现构建kdtree使用的 cv::Mat source是局部变量,被释放后,kdtree被破坏,于是把cv::Mat source定义为全局变量即可。 最主要的问题是 opencv的矩阵如果是浅拷贝的话,有一个引用计数的问题,如果引用计数为0,那么数据会被释放。

int main() {int queryNum = 3;//用于设置返回邻近点的个数vector<float> vecQuery(2);//存放查询点的容器vector<int> vecIndex(queryNum);//存放返回的点索引vector<float> vecDist(queryNum);//存放距离cv::flann::SearchParams params(32);//设置knnSearch搜索参数cv::flann::KDTreeIndexParams indexParams(2);vecQuery[0] = 3, vecQuery[1] = 4;cv::Mat source;vector<cv::flann::Index*> kdtrees;{vector<cv::Vec2d> features = { { 1,1 },{ 2, 2 },{ 3, 3 },{ 4, 4 },{ 2, 4 } };source = cv::Mat(features).reshape(1);source.convertTo(source, CV_32F);cv::flann::Index* kdtree = new cv::flann::Index(source, indexParams);kdtrees.push_back(kdtree);}kdtrees[0]->knnSearch(vecQuery, vecIndex, vecDist, queryNum, params);for (int i = 0; i < vecIndex.size(); i++)cout << "nearest id: " << vecIndex[i] << "\tdist:" << vecDist[i] << endl;return 0;
}

opencv kdtree的用法相关推荐

  1. 关于OpenCV中常见函数用法总结

    关于OpenCV中常见函数用法总结 一 一般Mat的赋值操作 二 求Mat中的最大值以及最小值 三 randn()函数给图像添加高斯噪声 四 mean()函数的用法 五 系统计时器 六 矩阵之间的四则 ...

  2. VTK:KDTree时序用法实战

    VTK:KDTree时序用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkAxis.h> #include <vtkChartXY.h> ...

  3. OpenCV cv::split用法的实例(附完整代码)

    OpenCV cv::split用法的实例 OpenCV cv::split用法的实例 OpenCV cv::split用法的实例 #include <iostream> #include ...

  4. OpenCV cv::reduce用法的实例(附完整代码)

    OpenCV cv::reduce用法的实例 OpenCV cv::reduce用法的实例 OpenCV cv::reduce用法的实例 #include <iostream> #incl ...

  5. OpenCV cv::merge用法的实例(附完整代码)

    OpenCV cv::merge用法的实例 OpenCV cv::merge用法的实例 OpenCV cv::merge用法的实例 #include <iostream> #include ...

  6. OpenCV Mat主要用法(2)_MatExpr

    在<OpenCV Mat主要用法(1)>主要是详细分析了Mat类中的主要Method用法,可以了解到Mat中常用的创建,访问,变量等一些方法,但是有时候还远远不够.OpenCV Mat主要 ...

  7. OpenCV Mat主要用法(1)

    Mat 为OpenCV中的核心数据结构,主要负责图像数据的保存,Mat创建方法有很多种 Mat构造函数 可以使用Mat构造函数,创建Mat,Mat构造函数有多种形式的参数,来满足要求 Mat 主要构造 ...

  8. opencv Mser的用法

    opencv Mser的用法 delta it compares (size_i − size{i−delta}) / size_{i−delta}, default 5 _min_area prun ...

  9. c++ opencv函数putText用法详解

    c++ opencv函数putText用法详解 #include <stdio.h> #include <iostream> #include <opencv2/open ...

最新文章

  1. 解决方案:__init__() got an unexpected keyword argument ‘kill_previous‘
  2. 转: GridView:当鼠标滑过,行的背景颜色发生变化
  3. Linux/Debian/Ubuntu报错解决:W: Target Packages (main/binary-amd64/Packages) is configured multiple times
  4. 趣味理解:三层架构与养猪—《.NET深入体验与实战精要》
  5. http简介看这篇就够了
  6. java8 stream ,filter 等功能代替for循环
  7. oracle 19602,Oracle CPU Costing
  8. 算法分析与设计——背包问题
  9. fpm工作流程(转)--写的很完整很明白
  10. SQL SERVER 查看所有存储过程或视图里包含某个关键字的查询语句
  11. google源码下载方法
  12. 世界上最神奇的数字是142857
  13. 隐藏程序在任务栏的图标
  14. hackerrank - Basic Join - Challenges
  15. python 全栈开发,Day46(列表标签,表格标签,表单标签,css的引入方式,css选择器)
  16. Windows系统通用定时关机命令
  17. Proteus仿真-数码管显示温度(实验三)
  18. 如何使用 notepad++ 对两个文件比较差异
  19. Java使用jfreechart画饼图_使用 jfreechart 生成 曲线、柱状图、饼状图、分布图 展示到JSP-2...
  20. MLX90640开发笔记(八)扩展知识-红外成像中的辐射率、灵敏度、精度、探测距离

热门文章

  1. hdoj 4875 逃生
  2. MP + QueryWrapper + 自定义SQL完成连表查询
  3. 狂涨结束:内存和固态硬盘终于要降价了
  4. 说句心里话python怎么写_说句心里话小升初满分作文
  5. 一封来自山东省食药监的感谢信
  6. 前沿重器[5] | 阿里小蜜的数据量分级处理机制
  7. Android实现应用内语言切换,android 应用内切换 多国语言
  8. SSM框架中医电子商务网站中医购物网站中医书籍中医药品药材(idea开发javaweb-javaee-j2ee-springboot)
  9. 方舟服务器 参数修改,《方舟:生存进化》单机模式游戏参数ini设置指南
  10. DIP数字图像处理-知识提纲