Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >nanoflann库

nanoflann库

作者头像
点云PCL博主
发布于 2019-07-30 08:14:34
发布于 2019-07-30 08:14:34
4.1K0
举报
文章被收录于专栏:点云PCL点云PCL

点云处理过程中可能会遇到寻找最临近点的问题,常用的解决方案就是用空间换效率。例如建立kd-tree等树状结构来代替遍历。

这里向大家介绍一个nanoflann工程,nanoflann 算法对fastann进行了改进,效率以及内存使用等方面都进行了优化,而且代码十分轻量级且开源,是一个不错的选择。工程代码下载地址 https://github.com/jlblancoc/nanoflann

1.介绍

nanoflann是一个c++11标准库,用于构建具有不同拓扑(R2,R3(点云),SO(2)和SO(3)(2D和3D旋转组))的KD树。nanoflann不需要编译或安装。你只需要#include <nanoflann.hpp>在你的代码中。

1.1 如何使用库

最简单的方法:将其include/nanoflann.hpp用于需要的地方。

1.2 代码示例

  1. KD-trees使用kdd_search()和查找radius_search() : pointcloud_kdd_radius.cpp
  2. 点云数据集上的KD树查找:pointcloud_example.cpp
  3. 在动态点云数据集上进行KD树查找:dynamic_pointcloud_example.cpp
  4. 旋转组(SO2)上的KD树查找:SO2_example.cpp
  5. 旋转组(SO3)上的KD树查找:SO3_example.cpp
  6. 使用外部适配器类在点云数据集上查找KD树:pointcloud_adaptor_example.cpp
  7. KD-tree使用在Eigen::Matrix<>:matrix_example.cpp上查找
  8. KD-tree查找std::vector<std::vector<T> >或std::vector<Eigen::VectorXd>:vector_of_vectors_example.cpp
  9. 如何构建索引并将其保存到磁盘供以后使用的示例:saveload_example.cpp

3. nanoflann可以做什么?

A.建立具有单一索引的KD树(没有随机化的KD树,没有大致的搜索)。快速,线程安全地查询KD树上最近的邻居。接口是:

1. nanoflann :: KDTreeSingleIndexAdaptor <>::knnSearch()

找到num_closest最近的邻居query_point[0:dim-1]。它们的索引存储在结果对象中。查看示例使用代码:

2. nanoflann :: KDTreeSingleIndexAdaptor <>::radiusSearch()

query_point[0:dim-1]在最大半径范围内查找所有邻居。输出作为对的向量给出,其中第一个元素是点索引,第二个元素是相应的距离。查看示例使用代码。

3. nanoflann :: KDTreeSingleIndexAdaptor<>::radiusSearchCustomCallback()

可以用于接收范围内找到的每个点的回叫。这在某些情况下可能更有效,而不是用结果构建一个巨大的向量对。

B. 使用2D和3D点云或N维数据集。

C. 直接使用Eigen::Matrix<>类(矩阵和向量向量)

D. 使用动态点云而无需重建整个kd-tree索引。

E. 使用距离度量标准:

o L1 (曼哈顿)

o L2 (欧几里得,赞成SSE2优化)。

o L2_Simple (欧几里得,用于像点云这样的低维数据集)。

o SO2 (用于旋转组SO2)。

o SO3 (欧几里得,对于旋转组SO3)。

F. 将构建的索引保存并加载到磁盘。

1.4 Nanoflann不能做什么?

使用除L1,L2,SO2和SO3以外的其他距离度量。

支持SE(3)组。

只有C ++接口存在:不支持C,MATLAB或Python

2.如何选择KD树参数?

2.1 KDTreeSingleIndexAdaptorParams::leaf_max_size

KD树它有一个根节点,一组中间节点,最后是没有孩子的“叶”节点。点只存储在叶节点中。每个叶子都包含一个列表,其中包含哪些点落入其范围内。在构建树的同时,递归地分割节点,直到内部的点数等于或低于某个阈值。那是leaf_max_size。在进行查 时,“树算法”通过选择叶节点结束,然后在叶中的所有元素内对查询的最近点执行线性搜索(一个接一个)。所以,leaf_max_size必须将其设定为合适的值:

· 较大的值意味着树会更快地构建(因为树会更小),但是每个查询会更慢(因为叶子中的线性搜索要完成更多的点)。

· 较小的值将构建树慢得多(将会有许多树节点),但查询会更快......因为搜索的“树部分”(对数复杂度)仍然有很高的成本。

选择哪个数字确实取决于应用程序,甚至取决于处理器高速缓存的大小,因此理想情况下应该执行一些基准测试以最大限度地提高效率。

但为了帮助选择一个比较合适的参数作为一个基准,我提供了以下两个基准。每个图表代表leaf_max_size1到10K之间不同值的树构建(水平)和查询(垂直)时间(95%不确定性椭圆,由于对数标度而变形)。

· 一个100K点云,均匀分布(每个点有(x,y,z)float坐标):

· 一个来自真实数据集(scan_071_points.dat来自弗莱堡校区360数据集,每个点具有(x,y,z)float坐标)的大约150K点云:

因此,对于查询成本占主导地位的应用(例如ICP),似乎leaf_max_size10到50之间是最佳的。目前,其默认值为10。

3.性能

3.1 nanoflann:更快,更少的内存使用

3.2 原始flann对比nanoflann

许多点云算法(如ICP)中最耗时的部分是查询最近邻居的KD树。因此这个操作是最重要的。nanoflann相对于原始flann实现可节省大约50%的时间(此图表中的时间以微秒为单位):

由于模板化代码的原因,在构建KD树索引时还节省了一些时间,避免在辅助矩阵中复制数据(下图中的时间以毫秒为单位):

4.其他KD树项目

FLANN - Marius Muja和David G. Lowe(不列颠哥伦比亚大学)。

FASTANN - James Philbin(VGG,牛津大学)。

ANN - David M. Mount和Sunil Arya(马里兰大学)。

libkdtree ++ - Martin F. Krafft等人。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 点云PCL 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档