C++-使用opencv-frann查找最近的邻居
C++ - Finding nearest neighbor using opencv flann
我有两组点(cv::Point2f):setA和setB。对于集合A中的每个点,我想找到它在集合B中最近的邻居。所以,我尝试了两种方法:
-
线性搜索:对于集合A中的每个点,只需扫描集合B中的所有点即可找到最近的点。
-
使用opencv-kd树:
_首先,我使用opencv-frann:为setB构建了一个kd树
cv::flann::KDTreeIndexParams indexParams; cv::flann::Index kdTree(cv::Mat(setB).reshape(1), indexParams);
_然后,对于集合A中的每个点,我进行查询以找到最近的邻居:
kdTree.knnSearch(point_in_setA, indices, dists, maxPoints);
注意:我将maxPoints设置为1,因为我只需要最接近的一个。
我做了一些研究,得出了每个案例的一些时间复杂性:
-
线性搜索:O(M*N)
-
Kd树:NlogN+MlogN=>第一项用于构建Kd树,第二项用于查询
其中M是集合A中的点数,N是集合B的点数。N的范围为100~1000,M的范围为10000~100000。
因此,kd树应该比线性搜索方法运行得更快。然而,当我在笔记本电脑上进行真正的测试时,结果是kd-tree方法比线性搜索慢(0.02~0.03s vs 0.4~0.5s)
当我进行评测时,我在knnSearch()函数上获得了热点,它占用了20.3%的CPU时间,而线性搜索占用了7.9%。
嗯,我看了一些网上的文章,他们说查询kd树通常需要logN。但我不确定opencv是如何实现的。
有人知道这里出了什么问题吗?kd树中是否有我应该调整的参数,或者我在代码或计算中的某个地方犯了错误?
摘自Flann文档。对于低维数据,应使用KDTreeSingleIndexParams。
KDTreeSingleIndexParams
当传递这种类型的对象时,索引将包含一个为搜索低维数据(例如3D点云)而优化的kd树,在您的情况下是2D点。您可以使用leap_max_size参数并对结果进行评测。
struct KDTreeSingleIndexParams : public IndexParams
{
KDTreeSingleIndexParams( int leaf_max_size = 10 );
};
max leaf size: The maximum number of points to have in a leaf for not
branching the tree any more
O(log(N))并不一定意味着它比O(N)快。这只适用于足够大的N。你的N是一个相当小的数字。如果你的kd树包含数百万个元素,你可能会看到线性扫描和对数搜索之间的区别。
所以我的猜测是,你花了很多时间在开销上,比如构建树,对于小N来说,这比在没有任何开销的情况下扫描这个相当小的列表要慢。
- 查找最近配对时的OpenMP竞赛条件
- 如何获取pcl迭代最近点(ICP)的迭代点数?
- 优化在 Z^3 中查找邻居
- 如何找到给定点的最近平方
- 将消息从节点发送到其邻居
- 将前向声明的结构替换为最近定义的结构
- Nanoflann发现邻居提出段错误
- 应该如何编写用于计算最近点距离的C++函数?
- 最近的邻居用nanoflann搜索
- GCC:--静态链接到pthread的整个存档配方在最近的GCC版本中停止工作
- 向下四舍五入到五个c++的最近倍数
- 在 3D 点云、GPU 中查找最近的邻居
- 多线程程序中的K最近的邻居
- C++-使用opencv-frann查找最近的邻居
- 优化最近邻居大小调整算法以提高速度
- 在 KD 树中查找最近的邻居
- 查找最近的邻居-OpenCV
- 是否存在使用用户提供的提示的最近邻居数据结构
- c++一个固定大小的优先级队列,用于存储k个最近邻居
- 在direct3D9中有没有一种方法可以通过最近的邻居来缩放精灵