作用:使用体素化网格方法实现下采样,可在保持点云形状特征的情况下减少点云的数量;在提高配准、曲面重建、形状识别等算法的速度。
原理:PCL实现的VoxelGrid类通过输入的点云数据创建一个三维体素栅格,然后在每个体素内,用体素中所有点的重心来近似显示体素中其他点,这样该体素内所有点就用一个重心点最终表示,对于所有体素处理后得到过滤后的点云。
效果: 这种方法比用体素中心来逼近的方法更慢,但它对于采样点对应曲面的表示更为准确。
代码展示:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// 加载点云
// 点云文件地址:https://github.com/PointCloudLibrary/data/blob/master/tutorials/table_scene_lms400.pcd
pcl::io::loadPCDFile<pcl::PointXYZ>("source/table_scene_lms400.pcd",*cloud);
// 创建滤波器对象
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud (cloud); //设置需要滤波的点云
sor.setLeafSize (0.1f, 0.1f, 0.1f); //设置滤波时创建的体素体积为0.1m3
sor.filter (*cloud_filtered); //执行滤波处理,并将结果输出cloud_filtered
cout << "Cloud after filtering: " << cloud_filtered->points.size() << endl;
pcl::visualization::PCLVisualizer::Ptr view(new pcl::visualization::PCLVisualizer("ShowCloud"));
// 创建两个视口: 第一个用于显示原始点云, 第二个用于显示滤波后的点云
int v1(0);
view->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
view->setBackgroundColor(0, 0, 0, v1);
view->addText("Raw point clouds", 10, 10, "v1_text", v1);
int v2(0);
view->createViewPort(0.5, 0.0, 1, 1.0, v2);
view->setBackgroundColor(0.1, 0.1, 0.1, v2);
view->addText("filtered point clouds", 10, 10, "v2_text", v2);
view->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud", v1);
view->addPointCloud<pcl::PointXYZ>(cloud_filtered, "cloud_filtered", v2);
// 设置点云的渲染颜色
view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "sample cloud", v1);
view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cloud_filtered", v2);
view->addCoordinateSystem(1.0);
view->initCameraParameters();
while (!view->wasStopped()) {
view->spinOnce(100);
}
return 0;
}
结果展示