(1)下采样 Downsampling
一般下采样是通过构造一个三维体素栅格,然后在每个体素内用体素内的所有点的重心近似显示体素中的其他点,这样体素内所有点就用一个重心点来表示,进行下采样的来达到滤波的效果,这样就大大的减少了数据量,特别是在配准,曲面重建等工作之前作为预处理,可以很好的提高程序的运行速度。
pcl::VoxelGrid<pcl::PointXYZ> filter; filter.setInputCloud(cloud); filter.setLeafSize(0.01f, 0.01f, 0.01f); // 设置体素栅格的大小为 1x1x1cm filter.filter(*filteredCloud);
(2)均匀采样:这个类基本上是相同的,但它输出的点云索引是选择的关键点在计算描述子的常见方式。
pcl::UniformSampling<pcl::PointXYZ> filter; filter.setInputCloud(cloud); filter.setRadiusSearch(0.01f); // We need an additional object to store the indices of surviving points. pcl::PointCloud<int> keypointIndices; filter.compute(keypointIndices); pcl::copyPointCloud(*cloud, keypointIndices.points, *filteredCloud);
(3)增采样 :增采样是一种表面重建方法,当你有比你想象的要少的点云数据时,增采样可以帮你恢复原有的表面(S),通过内插你目前拥有的点云数据,这是一个复杂的猜想假设的过程。所以构建的结果不会百分之一百准确,但有时它是一种可选择的方案。所以,在你的点云云进行下采样时,一定要保存一份原始数据!
// 滤波对象 pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ> filter; filter.setInputCloud(cloud); //建立搜索对象 pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree; filter.setSearchMethod(kdtree); filter.setSearchRadius(0.03); //设置搜索邻域的半径为3cm // Upsampling 采样的方法有 DISTINCT_CLOUD, RANDOM_UNIFORM_DENSITY // 采样的半径是 filter.setUpsamplingMethod(pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointXYZ>::SAMPLE_LOCAL_PLANE); filter.setUpsamplingRadius(0.03); // 采样步数的大小 filter.setUpsamplingStepSize(0.02); filter.process(*filteredCloud);
运行结果:
(4)表面重建
深度传感器的测量是不准确的,和由此产生的点云也是存在的测量误差,比如离群点,孔等表面,可以用一个算法重建表面,遍历所有的点云和插值数据,试图重建原来的表面。比如增采样,PCL使用MLS算法和类。执行这一步是很重要的,因为由此产生的点云的法线将更准确。
pcl::MovingLeastSquares<pcl::PointXYZ, pcl::PointNormal> filter; filter.setInputCloud(cloud); filter.setSearchRadius(0.03); filter.setPolynomialFit(true); filter.setComputeNormals(true); pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree; filter.setSearchMethod(kdtree); filter.process(*smoothedCloud);
原始图像(带颜色信息)
增采样平滑后(没有颜色信息)
地址:https://github.com/realingy/pcl_process_examples/tree/master/pcl_base