NDT 公式推导及源码解析(1)

NDT 的论文在去年就看了,代码的话也零零散散看了一些,但直到最近才决定抽出时间把 NDT 的论文和代码重新整理记录一下,方便日后学习。本文主要参考的论文有 [1,2,3],其中 [1] 是 NDT 被首次提出时发表的论文,如论文名所指出的——NDT 是一种 laser scan matching 方法。[2] 则是 Magnusson 等人将 NDT 从 2D 扩展到 3D 中的论文,[3] 是 Magnusson 的博士论文,论文的内容很多,我阅读的主要是介绍 NDT 的第六章,内容十分清晰详实。[4,5] 则是在 [3] 中的参考文献找到的论文,挑着 [4] 的高斯近似看了一下。

简单介绍

NDT 的直观介绍的话建议看 [1] 或 [7],这里就不重复赘述了,本文主要关注的还是 NDT 的公式推导(不含 line search 部分的公式)和源码解析(不含 line search 部分的代码),公式主要来自于 [3] 第六章,代码主要来自于 Autoware[6] 的 ndt_cpu 库。

6.1 NDT for representing surfaces

直接使用点云的缺点是:1. 点云中没有直接包含平面的特征信息,如朝向、平滑性等;2. 直接使用点云有点 inefficient,需要大量存储空间。NDT 则使用局部 PDF(probability density function) 来描述点云的局部分布

(6.1) p ( x ⃗ ) = 1 ( 2 π ) D / 2 ∣ Σ ∣ e x p ( − ( x ⃗ − μ ⃗ ) T Σ − 1 ( x ⃗ − μ ⃗ ) 2 ) p(\vec{x}) = \frac{1}{(2\pi)^{D/2}\sqrt{|\Sigma|}}exp(-\frac{(\vec{x}-\vec{\mu})^T\Sigma^{-1}(\vec{x}-\vec{\mu})}{2}) \tag{6.1} p(x )=(2π)D/2Σ 1exp(2(x μ )TΣ1(x μ ))(6.1)
μ ⃗ = 1 m ∑ k − 1 m y k ⃗ , Σ = 1 m − 1 ∑ k − 1 m ( y k ⃗ − μ ⃗ ) ( y k ⃗ − μ ⃗ ) T \vec{\mu} = \frac{1}{m}\sum\limits_{k-1}^m \vec{y_k}, \\ \Sigma = \frac{1}{m-1}\sum\limits_{k-1}^m (\vec{y_k} - \vec{\mu})(\vec{y_k} - \vec{\mu})^T μ =m1k1myk ,Σ=m11k1m(yk μ )(yk μ )T
其好处是:1. 正态分布局部是平滑的,具有连续的导数;2. 每个 PDF 可以认为是局部平面的近似,描述了平面的位置(均值 μ \mu μ)、朝向、形状和平滑性(协方差 Σ \Sigma Σ 的特征向量和特征值,特征向量描述的点云分布的主成分(principal components))等特征。在 2D 场景中,1. 如果方差比较近似,局部点云的形状为 point;2. 如果一个方差远大于另一个方差,局部点云的形状为 line。在3D 场景中,1. 如果方差比较近似,局部点云形状为 point/sphere;2. 如果一个方差远大于另外两个方差,局部点云形状为 line;如果一个方差远小于另外两个方差,局部点云形状为 plane。如图 6.4。

6.2 NDT scan registration

NDT scan registration 的目标很简单,最大化下面似然函数:

(6.5) Ψ = ∏ k − 1 n p ( T ( p ⃗ , x k ⃗ ) ) \Psi = \prod\limits_{k-1}^n p(T(\vec{p}, \vec{x_k})) \tag{6.5} Ψ=k1np(T(p ,xk ))(6.5)

其中 χ = { x 1 ⃗ , . . . , x n ⃗ } \chi = \{\vec{x_1},...,\vec{x_n}\} χ={ x1 ,...,xn } 是要匹配的 source 点云, T ( p ⃗ , x ⃗ ) T(\vec{p}, \vec{x}) T(p ,x ) 表示将点 x ⃗ \vec{x} x 通过位姿 p ⃗ \vec{p} p 旋转平移到 target 点云中。通过负对数将原问题转换为最小化问题:

(6.6) − l o g Ψ = − ∑ k = 1 n l o g ( p ( T ( p ⃗ , x k ⃗ ) ) ) -log \Psi = -\sum\limits_{k=1}^n log(p(T(\vec{p}, \vec{x_k}))) \tag{6.6} logΨ=k=1nlog(p(T(p ,xk )))(6.6)

虽然论文里说公式里的概率分布 PDF 并不局限与正态分布,只要能描述点云的局部特征并且对噪点鲁棒就行,但要想换成其他分布估计要花费挺大精力去做实验室

  • 12
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
NDT算法(Normal Distributions Transform)是一种点云配准算法,用于将不同视角或不同时间的点云数据进行配准。其基本思想是将点云数据转化为高斯分布函数,再进行匹配计算。以下是NDT算法的代码及仿真方法: 1. NDT算法代码(C++实现) ```c++ #include <pcl/point_types.h> #include <pcl/registration/ndt.h> #include <pcl/io/pcd_io.h> #include <pcl/visualization/pcl_visualizer.h> int main(int argc, char **argv) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZ>); // 读取点云数据 pcl::io::loadPCDFile<pcl::PointXYZ>("cloud_in.pcd", *cloud_in); pcl::io::loadPCDFile<pcl::PointXYZ>("cloud_out.pcd", *cloud_out); // 点云配准 pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt; ndt.setInputSource(cloud_in); ndt.setInputTarget(cloud_out); pcl::PointCloud<pcl::PointXYZ>::Ptr aligned(new pcl::PointCloud<pcl::PointXYZ>); ndt.align(*aligned); // 可视化结果 pcl::visualization::PCLVisualizer viewer("NDT"); viewer.setBackgroundColor(0, 0, 0); viewer.addPointCloud<pcl::PointXYZ>(cloud_in, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud_in, 0, 255, 0), "cloud_in"); viewer.addPointCloud<pcl::PointXYZ>(cloud_out, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud_out, 255, 0, 0), "cloud_out"); viewer.addPointCloud<pcl::PointXYZ>(aligned, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(aligned, 0, 0, 255), "aligned"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_in"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_out"); viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "aligned"); viewer.spin(); return 0; } ``` 2. NDT算法仿真方法 可以使用PCL(Point Cloud Library)库中的示例数据进行仿真。具体步骤如下: - 下载PCL库,并安装相关依赖项。 - 在终端中运行以下命令,下载示例数据: ``` cd ~/pcl_examples wget https://github.com/PointCloudLibrary/data/blob/master/tutorials/table_scene_lms400.pcd ``` - 将示例数据进行复制,生成两份数据cloud_in.pcd和cloud_out.pcd: ``` cp table_scene_lms400.pcd cloud_in.pcd cp table_scene_lms400.pcd cloud_out.pcd ``` - 修改cloud_out.pcd中的点云数据,使其产生一定的平移和旋转。 - 编译并运行NDT算法代码,得到点云配准结果。 以上是NDT算法的代码及仿真方法,其中代码使用了PCL库中的NDT算法实现,可以对点云数据进行配准处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值