官网下载地址
下载AllInOne 以及 pdb。
%PCL_ROOT%\bin;
%PCL_ROOT%\3rdParty\FLANN\bin;
%PCL_ROOT%\3rdParty\VTK\bin;
%PCL_ROOT%\3rdParty\Qhull\bin;
%PCL_ROOT%\3rdParty\OpenNI2\Tools
官网下载地址
Qt安装路径\
Qt安装路径\msvc2017_64\bin
前面安装PCL时有讲到过,PCL默认的三方库中是没有编译好的Qt库的,(默认的3rdParty中的VTK是没有Qt相关的)因此需要下载与已安装好的PCL版本对应的VTK库,然后自行编译出相关的VTK库以及QT插件。
官网下载地址
VTK 与PCL 版本对应关系可自行百度
$(PCL_ROOT)\include\pcl-1.11;
$(PCL_ROOT)\3rdParty\Eigen\eigen3;
$(PCL_ROOT)\3rdParty\Qhull\include;
$(PCL_ROOT)\3rdParty\FLANN\include;
$(PCL_ROOT)\3rdParty\OpenNI2\Include;
$(PCL_ROOT)\3rdParty\VTK\include\vtk-8.2;
$(PCL_ROOT)\3rdParty\Boost\include\boost-1_74;
$(PCL_ROOT)\lib;
$(PCL_ROOT)\3rdParty\VTK\lib;
$(PCL_ROOT)\3rdParty\Qhull\lib;
$(PCL_ROOT)\3rdParty\Boost\lib;
$(PCL_ROOT)\3rdParty\FLANN\lib;
$(PCL_ROOT)\3rdParty\OpenNI2\Lib;
$(PCL_ROOT)\lib 路径下的文件名(添加时注意添加时候区分debug、release版本):
$(PCL_ROOT)\3rdParty\VTK\lib 路径下的文件名:
$(PCL_ROOT)\3rdParty\Qhull\lib 路径下的文件名:
$(PCL_ROOT)\3rdParty\Boost\lib 路径下的文件名:
$(PCL_ROOT)\3rdParty\FLANN\lib 路径下的文件名:
$(PCL_ROOT)\3rdParty\OpenNI2\Lib 路径下的文件名:
#include
#include
#include
#include // NDT配准
#include // 体素滤波
#include
#include
#include
using namespace std;
int
main(int argc, char** argv)
{
pcl::console::TicToc time;
// 加载点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr source_cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("room_scan2.pcd", *source_cloud);
pcl::io::loadPCDFile<pcl::PointXYZ>("room_scan1.pcd", *target_cloud);
if (source_cloud->empty() || target_cloud->empty())
{
cout << "请确认点云文件名称是否正确" << endl;
return -1;
}
else {
cout << "从目标点云读取 " << target_cloud->size() << " 个点" << endl;
cout << "从源点云中读取 " << source_cloud->size() << " 个点" << endl;
}
//将输入的源点云过滤到原始尺寸的大概10%以提高匹配的速度。
pcl::PointCloud<pcl::PointXYZ>::Ptr filtered_cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::ApproximateVoxelGrid<pcl::PointXYZ> approximate_voxel_filter;
approximate_voxel_filter.setInputCloud(source_cloud);
approximate_voxel_filter.setLeafSize(0.5, 0.5, 0.5);
approximate_voxel_filter.filter(*filtered_cloud);
cout << "Filtered cloud contains " << filtered_cloud->size() << " data points " << endl;
// -------------NDT进行配准--------------
time.tic();
pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt;
ndt.setStepSize(0.5); // 为More-Thuente线搜索设置最大步长
ndt.setResolution(2); // 设置NDT网格结构的分辨率(VoxelGridCovariance)
ndt.setMaximumIterations(35); // 设置匹配迭代的最大次数
ndt.setInputSource(filtered_cloud); // 设置要配准的点云
ndt.setInputTarget(target_cloud); // 设置点云配准目标
ndt.setTransformationEpsilon(0.001); // 为终止条件设置最小转换差异
//-------------计算变换矩阵--------------
//设置使用机器人测距法得到的初始对准估计结果
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();
//计算需要的刚体变换以便将输入的点云匹配到目标点云
pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud(new pcl::PointCloud<pcl::PointXYZ>);
ndt.align(*output_cloud, init_guess);
cout << "NDT has converged:" << ndt.hasConverged()
<< " score: " << ndt.getFitnessScore() << endl;
cout << "Applied " << ndt.getMaximumIterations() << " NDT iterations in " << time.toc() << " ms" << endl;
cout << "变换矩阵:\n" << ndt.getFinalTransformation() << endl;
//使用变换矩阵对未过滤的源点云进行变换
pcl::transformPointCloud(*source_cloud, *output_cloud, ndt.getFinalTransformation());
//保存转换的源点云
//pcl::io::savePCDFileASCII("30.00.pcd", *output_cloud);
//-------------点云可视化----------------
boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("3D-NDT Registration"));
viewer->setBackgroundColor(0, 0, 0);
//对源点云着色并可视化
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>source_color(source_cloud, 0, 0, 255);
viewer->addPointCloud<pcl::PointXYZ>(source_cloud, source_color, "source cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "source cloud");
//对目标点云着色(红色)并可视化
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>target_color(target_cloud, 255, 0, 0);
viewer->addPointCloud<pcl::PointXYZ>(target_cloud, target_color, "target cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target cloud");
//对转换后的源点云着色(绿色)并可视化
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>output_color(output_cloud, 0, 255, 0);
viewer->addPointCloud<pcl::PointXYZ>(output_cloud, output_color, "output cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "output cloud");
// 启动可视化
//viewer->addCoordinateSystem(0.1);
//viewer->initCameraParameters();
// 等待直到可视化窗口关闭。
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return (0);
}