一、方法原理
使用体素化网格方法实现下采样,即减少点的数量,减少点云数据,并同时保存点云的形状特征, 在提高配准,曲面重建,形状识别等算法速度中非常实用, 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>
#include <boost/thread/thread.hpp>
using namespace std;
int main (int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
// 读入点云数据
pcl::PCDReader reader;
reader.read ("table_scene_lms400.pcd", *cloud);
cout << "PointCloud before filtering: " << *cloud <<endl;
// 创建滤波器对象
pcl::VoxelGrid<pcl::PointXYZ> sor;
sor.setInputCloud (cloud);
sor.setLeafSize (0.01f, 0.01f, 0.01f);
sor.filter (*cloud_filtered);
cout << "PointCloud after filtering: " << *cloud_filtered<<endl;
// 保存
pcl::PCDWriter writer;
writer.write<pcl::PointXYZ>("2f.pcd", *cloud_filtered, false);
// 可视化
boost::shared_ptr<pcl::visualization::PCLVisualizer> view(new pcl::visualization::PCLVisualizer("ShowCloud"));
int v1(0); // 赋值
view->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 窗口位置 xmin, ymin, xmax, ymax
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);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
三、效果展示
![](https://i-blog.csdnimg.cn/blog_migrate/203463e2a06ac3f124e89c3061832eab.png)
四、注意
- PCL点云读取速度必减慢,运行程序后稍微等待片刻。