普通体素降采样
直接调用voxel_grid库,参考官方教程,只需要设置体素的大小setLeafSize(x, y, z)
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <iostream> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/filters/voxel_grid.h>
int main () { pcl::PCLPointCloud2::Ptr cloud (new pcl::PCLPointCloud2 ()); pcl::PCLPointCloud2::Ptr cloud_filtered (new pcl::PCLPointCloud2 ());
pcl::PCDReader reader; reader.read ("table_scene_lms400.pcd", *cloud); std::cerr << "PointCloud before filtering: " << cloud->width * cloud->height << " data points (" << pcl::getFieldsList (*cloud) << ")." << std::endl; pcl::VoxelGrid<pcl::PCLPointCloud2> 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) << ")." << std::endl;
return (0); }
|
然而,对于大规模的点云(如点个数超过100000),就会导致格点数超过整型最大值,报错:
1
| Leaf size is too small for the input dataset. Integer indices would overflow.
|
此时可以采用八叉树结构,将整个点云分成有大小限制的若干个叶节点,对每个叶节点分别做体素过滤,再合起来
octree体素过滤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZI>());
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZI>());
pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_tmp(new pcl::PointCloud<pcl::PointXYZI>()); pcl::PointCloud<pcl::PointXYZI>::Ptr cloud_tmp_ds(new pcl::PointCloud<pcl::PointXYZI>());
static float kLeafSize = 0.2; pcl::VoxelGrid<pcl::PointXYZI> filter_map; filter_map.setLeafSize(kLeafSize, kLeafSize, kLeafSize);
cloud_out->clear(); pcl::octree::OctreePointCloud<pcl::PointXYZI> octree{1250 * kLeafSize}; octree.setInputCloud(cloud_map); octree.addPointsFromInputCloud();
for (auto it = octree.leaf_depth_begin(); it != octree.leaf_depth_end(); ++it) { auto ids = it.getLeafContainer().getPointIndicesVector(); cloud_tmp->clear(); for (auto id : ids) { cloud_tmp->push_back(octree.getInputCloud()->points[id]); } filter_map.setInputCloud(cloud_tmp); filter_map.filter(*cloud_tmp_ds); *cloud_out += *cloud_tmp_ds; }
|