Leaf size is too small for the input dataset 解决办法

问题描述

在使用PCL的voxelgrid filter时,若点云过大,而设置的voxel比较小,可能会导致voxel的数量超过int32的上限,从而会出现警告:“Leaf size is too small for the input dataset”。

通用解决办法

  • 此文提出了几个解决办法:
  1. 对精度要求没那么高的话,可以将leaf size大小设置大一些。
  2. 将要降采样的点云先分割成几块、在做降采样。
  3. 使用 OctreeVoxelGridFilter,参考PCL论坛。

My solution

但上述解决办法我觉得并不好用,因此,我通过更改VoxelGrid的代码,实现了对比较大点云的降采样支持。
具体思路为若voxel数目溢出,则使用二分法将点云分成两块,然后递归调用voxelgrid即可。

  • 方案一
    更改PCL原始代码,找到“Leaf size is too small for the input dataset. Integer indices would overflow”所在位置,并将if中余下部分更改为以下代码:
pcl::PointCloud<PointT>cloud1,cloud2,cloud1f,cloud2f;pcl::PassThrough<PointT>pass;if(dx>dy&&dx>dz){pass.setInputCloud(input_);pass.setFilterFieldName("x");pass.setFilterLimits(min_p[0],min_p[0]+(max_p[0]-min_p[0])/2);pass.filter(cloud1);pass.setFilterLimitsNegative(true);pass.filter(cloud2);}elseif(dy>dx&&dy>dz){pass.setInputCloud(input_);pass.setFilterFieldName("y");pass.setFilterLimits(min_p[1],min_p[1]+(max_p[1]-min_p[1])/2);pass.filter(cloud1);pass.setFilterLimitsNegative(true);pass.filter(cloud2);}else{pass.setInputCloud(input_);pass.setFilterFieldName("z");pass.setFilterLimits(min_p[2],min_p[2]+(max_p[2]-min_p[2])/2);pass.filter(cloud1);pass.setFilterLimitsNegative(true);pass.filter(cloud2);}VoxelGrid voxelGrid=*this;voxelGrid.setInputCloud(cloud1.makeShared());voxelGrid.filter(cloud1f);voxelGrid.setInputCloud(cloud2.makeShared());voxelGrid.filter(cloud2f);output=cloud1f+cloud2f;return;
  • 方案二
    使用我写好的VoxelGridLarge代码。

由于不同的人的遇到的问题往往不一样,如何往工程中应用建议参考我之前的代码(虽然不是解决leafsize的代码,但往工程中应用的思路和写法是一样的):github仓库 或者 gitee仓库