没有合适的资源?快使用搜索试试~ 我知道了~
资源详情
资源评论
资源推荐
如何使用正态分布变换
在本教程中,我们将介绍如何使用正态分布变换(NDT)算法来确定两个超过 100,000 点的两
个大点云之间的刚性变换。NDT 算法是一种配准算法,使用应用于 3D 点统计模型的标准优化
技术来确定两个点云之间最可能的配准。有关 NDT 算法内部工作原理的更多信息,请参阅
Martin Magnusson 博士的博士论文“三维正态分布变换 - 用于配准,表面分析和环路检测的高
效表示法”。
代码
首先,下载数据集 room_scan1.pcd
和 room_scan2.pcd
并将它们保存到磁盘。这些点云包含
来自不同视角的同一房间的 360 度扫描。
然后,在您最喜欢的编辑器中创建一个文件,并将以下内容放入。我用
normal_distributions_transform.cpp 这个教程。
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#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>
#include <boost/thread/thread.hpp>
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;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 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.
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).
pcl::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);
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//Setting Resolution of NDT grid structure
(VoxelGridCovariance).
ndt.setResolution (1.0);
// 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);
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
剩余10页未读,继续阅读
伯玡
- 粉丝: 4
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0