1. NDT介绍

Normal Distributions Transform (NDT) 算法对于大型点云比较有效,它使用3D点云统计模型的标准最优化技术来确定两个点云可能的配准。NDT配准算法耗时稳定,跟初值相关不大,初值误差大时,也能很好的纠正过来。

NDT算法步骤为:

  1. 将空间(reference scan)划分成各个格子cell
  2. 将点云投票到各个格子
  3. 计算格子的正态分布的参数
  4. 将第二幅scan的每个点按转移矩阵T的变换
  5. 第二幅scan的点落于reference的哪个格子,计算响应的概率分布函数
  6. 求所有点的最优值,目标函数为

如果想要了解更多信息可以查阅Martin Magnusson的2009年博士论文:《The Three-Dimensional Normal Distributions Transform – an Efficient Representation for Registration, Surface Analysis, and Loop Detection》

2. NDT代码示例

#include <iostream>
#include <thread>#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>#include <pcl/registration/ndt.h>
#include <pcl/filters/approximate_voxel_grid.h>#include <pcl/visualization/pcl_visualizer.h>using namespace std::chrono;int
main (int argc, char** argv)
{// Loading first scan of room.// 加载房间的第一次扫描点云数据作为目标pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud (new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ> ("room_scan1.pcd", *target_cloud) == -1){PCL_ERROR ("Couldn't read file room_scan1.pcd \n");return (-1);}std::cout << "Loaded " << target_cloud->size () << " data points from room_scan1.pcd" << std::endl;// Loading second scan of room from new perspective.// 加载从新视角得到的第二次扫描点云数据作为源点云pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud (new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ> ("room_scan2.pcd", *input_cloud) == -1){PCL_ERROR ("Couldn't read file room_scan2.pcd \n");return (-1);}std::cout << "Loaded " << input_cloud->size () << " data points from room_scan2.pcd" << std::endl;// Filtering input scan to roughly 10% of original size to increase speed of registration.// 将输入的扫描点云数据过滤到原始尺寸的10%以提高匹配的速度,只对源点云进行滤波,减少其数据量,而目标点云不需要滤波处理//因为在NDT算法中在目标点云对应的体素网格数据结构的统计计算不使用单个点,而是使用包含在每个体素单元格中的点的统计数据pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud (new pcl::PointCloud<pcl::PointXYZ>);pcl::ApproximateVoxelGrid<pcl::PointXYZ> approximate_voxel_filter;approximate_voxel_filter.setLeafSize (0.2, 0.2, 0.2);approximate_voxel_filter.setInputCloud (input_cloud);approximate_voxel_filter.filter (*filtered_cloud);std::cout << "Filtered cloud contains " << filtered_cloud->size ()<< " data points from room_scan2.pcd" << std::endl;// Initializing Normal Distributions Transform (NDT).//初始化ndtpcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt;// Setting scale dependent NDT parameters// Setting minimum transformation difference for termination condition.ndt.setTransformationEpsilon (0.01);//为终止条件设置最小转换差异// Setting maximum step size for More-Thuente line search.ndt.setStepSize (0.1);//为more-thuente线搜索设置最大步长//Setting Resolution of NDT grid structure (VoxelGridCovariance).ndt.setResolution (1.0); //设置NDT网格网格结构的分辨率(voxelgridcovariance)// Setting max number of registration iterations.//添加最大迭代次数限制能够增加程序的鲁棒性阻止了它在错误的方向上运行时间过长ndt.setMaximumIterations (35);// Setting point cloud to be aligned.ndt.setInputSource (filtered_cloud); //源点云// Setting point cloud to be aligned to.ndt.setInputTarget (target_cloud);//目标点云// Set initial alignment estimate found using robot odometry.// 设置使用机器人测距法得到的粗略初始变换矩阵结果Eigen::AngleAxisf init_rotation (0.6931, Eigen::Vector3f::UnitZ ());Eigen::Translation3f init_translation (1.79387, 0.720047, 0);Eigen::Matrix4f init_guess = (init_translation * init_rotation).matrix ();// Calculating required rigid transform to align the input cloud to the target cloud.// 计算需要的刚体变换以便将输入的源点云匹配到目标点云pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud (new pcl::PointCloud<pcl::PointXYZ>);ndt.align (*output_cloud, init_guess);//这个地方的output_cloud不能作为最终的源点云变换,因为上面对点云进行了滤波处理std::cout << "Normal Distributions Transform has converged:" << ndt.hasConverged ()<< " score: " << ndt.getFitnessScore () << std::endl;// Transforming unfiltered, input cloud using found transform.// 使用创建的变换对为过滤的输入点云进行变换pcl::transformPointCloud (*input_cloud, *output_cloud, ndt.getFinalTransformation ());// Saving transformed input cloud.// 保存转换后的源点云作为最终的变换输出pcl::io::savePCDFileASCII ("room_scan2_transformed.pcd", *output_cloud);// Initializing point cloud visualizer// 初始化点云可视化对象pcl::visualization::PCLVisualizer::Ptrviewer_final (new pcl::visualization::PCLVisualizer ("3D Viewer"));viewer_final->setBackgroundColor (0, 0, 0);// Coloring and visualizing target cloud (red).// 对目标点云着色可视化 (red).pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>target_color (target_cloud, 255, 0, 0);viewer_final->addPointCloud<pcl::PointXYZ> (target_cloud, target_color, "target cloud");viewer_final->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1, "target cloud");// Coloring and visualizing transformed input cloud (green).// 对转换后的源点云着色 (green)可视化.pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>output_color (output_cloud, 0, 255, 0);viewer_final->addPointCloud<pcl::PointXYZ> (output_cloud, output_color, "output cloud");viewer_final->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE,1, "output cloud");// Starting visualizerviewer_final->addCoordinateSystem (1.0, "global");//显示XYZ指示轴viewer_final->initCameraParameters ();//初始化摄像头参数// Wait until visualizer window is closed.while (!viewer_final->wasStopped ()){viewer_final->spinOnce (100);//std::this_thread::sleep_for(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}return (0);
}

未匹配的room_scan1和room_scan2如下图所示:

使用NDT匹配后的效果图如下所示:

【点云处理技术之PCL】点云配准算法之NDT相关推荐

  1. 【点云处理技术之PCL】随机采样一致算法(Random sample consensus,RANSAC)

    文章目录 1. RANSAC介绍 2. RANSAC与最小二乘法 3. RANSAC思路流程 4. 代码举例 1. RANSAC介绍 应用范围:曲线拟合.地面拟合.图像拼接. RANSAC是" ...

  2. 【点云处理技术之PCL】点云分割算法1——平面模型分割、圆柱模型分割和欧式聚类提取(含欧式聚类原理)

    文章目录 1. 平面分割 2. 圆柱分割 3. 欧式聚类分割 1. 平面分割 下列中,先随机创建了z=1.0的随机点,然后改变其中3个点的z值.最后,使用SACMODEL_PLANE平面模型对它进行拟 ...

  3. 分布式、云原生技术之后,分布式云或成数字化转型新利器

    编辑 | 宋 慧 出品 | CSDN云计算 头图 | 2021可信云大会现场 7月27日,2021年可信云大会在京顺利开幕.本届大会以"数字裂变,可信发展"为主题,云计算行业专家学 ...

  4. 【点云处理技术之PCL】range image——提取深度图像的边界并可视化

    有三种不同的边界: object borders:目标最外层的边界 veil points:障碍物边界和阴影边界之间的插值点 shadow border:与遮挡相邻的背景点 三种边界的示意图如下: # ...

  5. 【点云处理技术之PCL】PCL中的基本数据类型——PointCloud与PointT

    文章目录 0. PointCloud 1. PointXYZ--x,y,z 2. PointXYZI--x,y,z,intensity 3. PointXYZRGBA--x,y,z,r,g,b,a 4 ...

  6. 云开发技术应用python pdf_云开发技术应用python_云开发技术应用(Python)

    项目1 Python语言概述及安装.配置(1) 1.1 任务1 认识Python语言(1) 1.1.1 Python的起源和发展前景(1) 1.1.2 Python的优缺点(2) 1.1.3 Pyth ...

  7. PCL点云配准(1)

    在逆向工程,计算机视觉,文物数字化等领域中,由于点云的不完整,旋转错位,平移错位等,使得要得到的完整的点云就需要对局部点云进行配准,为了得到被测物体的完整数据模型,需要确定一个合适的坐标系,将从各个视 ...

  8. python数据处理高斯滤波_十大点云数据处理技术梳理

    研究点云数据时,感觉无从下手? 看看这十大点云数据处理技术,换个思路学点云. 点云 · 定义 简言之,在获取物体表面每个采样点的空间坐标后,得到的是一个点的集合,称之为"点云".包 ...

  9. 点云nurbs曲面重建c++代码_【科普】抢先收藏!点云数据处理技术概要

    关注公众号"三维前沿",获取更多倾斜摄影.激光点云资讯 研究点云数据时,感觉无从下手? 看看这十大点云数据处理技术,换个思路学点云. 点云 · 定义 简言之,在获取物体表面每个采样 ...

  10. 点云处理算法整理(超详细教程)十大点云数据处理技术梳理

    研究点云数据时,感觉无从下手? 看看这十大点云数据处理技术,换个思路学点云. 点云 · 定义 简言之,在获取物体表面每个采样点的空间坐标后,得到的是一个点的集合,称之为"点云".包 ...

最新文章

  1. Arduino软件开发环境搭建
  2. 《Linux内核设计与实现》读书笔记(8)--- 内核同步方法(2)
  3. ARM linux的启动部分源代码简略分析
  4. TCP/IP协议的SYN攻击
  5. SAP Spartacus B2B页面的List Component
  6. Oracle数据库在Nokia
  7. 计算机数据库原理试题,计算机科学与技术专业《数据库原理》模拟试题(B)
  8. 通过Etcd+Confd自动管理Haproxy(多站点)
  9. access的papersize命令_[access报表]报表中使用自定义纸张,及设置自定义纸张大小
  10. C语言CV10版怎么生成结果,CV学习笔记(十九):文本数据集生成(text_renderer)
  11. PTA编程总结3—抓老鼠啊~亏了还是赚了?
  12. Dubbo 快速入门教程
  13. php导出 excel
  14. 高中计算机基础知识操作题,高中信息技术-word上机操作题
  15. 解决Office2007安装时出现错误1706的方法(转载)
  16. 这个案例你可以直接拿去用。
  17. 什么是RF、IF信号
  18. openresty ngx.ctx表
  19. 数据库之Oracle笔试面试题收集(来自网络)
  20. 用MindMaster绘制思维导图

热门文章

  1. 程序员版本的八荣八耻,爱了
  2. 基础汇编语言程序设计
  3. 码农架构 | Spring Boot 实现通用 Auth 认证的 4 种方式
  4. Oracle Spatial 安装和使用
  5. 帝国cms 制作网站地图
  6. 【每天更新】2022年最新WordPress主题下载(2022-5-12)
  7. 微信公众号申请开通微信支付
  8. 写给人生的九封信,愿你的人生淡定从容,繁华似锦!!!
  9. 站队(使用插入排序完成) (Standard IO)————c++插入排序
  10. 为何要使用加密邮箱?