使用体素化网格方法实现下采样,即减少点的数量,减少点云数据,并同时保持点云的形状特征,在提高配准、曲面重建、形状识别等算法速度中非常实用。
PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格(可把体素栅格想象为微小的空间三维立方体的集合),然后在每个体素(即,三维立方体)内,用体素中所有点的重心来近似显示体素中其他点,这样该体素就内所有点就用一个重心点最终表示,对于所有体素处理后得到过滤后的点云。这种方法比用体素中心来逼近的方法更慢,但它对于采样点对应曲面的表示更为准确。
所以该类常用于对大数据量的下采样处理,特别是在配准、曲面重建等工作之前作为预处理,可以很好的提高程序的速度。
代码:
#include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/voxel_grid.h> #include <pcl/io/io.h> #include <pcl/visualization/cloud_viewer.h> int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>); pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZI>); // 填入点云数据 pcl::io::loadPCDFile("table_scene_lms400.pcd", *cloud); // 创建滤波器对象 pcl::VoxelGrid<pcl::PointXYZI> sor;//滤波处理对象 sor.setInputCloud(cloud); sor.setLeafSize(0.01f, 0.01f, 0.01f);//设置滤波器处理时采用的体素大小的参数 sor.filter(*cloud_filtered); std::cerr << "PointCloud after filtering: " << cloud_filtered->width * cloud_filtered->height << " data points (" << pcl::getFieldsList(*cloud_filtered) << ")."; pcl::visualization::CloudViewer viewer("Cloud Viewer"); //showCloud函数是同步的,在此处等待直到渲染显示为止 viewer.showCloud(cloud_filtered); while (!viewer.wasStopped()) { //在此处可以添加其他处理 } return (0); }
虽然处理后数据量大大减少,但很明显其所含有的形状特征与空间结构信息与原始点云差不多