哪个pcl过滤器用于对点云进行下采样

时间:2018-04-13 14:25:50

标签: c++ point-cloud-library point-clouds downsampling

我从自动驾驶机器人的激光雷达上得到了一个点云,但是要处理的数据太多了。

我已经实现了一个直通过滤器。

我确实得到了一个非常好的结果,我问自己是否有其他过滤器或方法我可以深入研究。

当然,我不是在寻找任何具体的东西,而是寻找方向或建议,因为我对pcl库很新,看起来非常庞大。

现在是我的过滤器:

    pcl::PointCloud<PointXYZIR>::Ptr cloudInput;
    cloudInput.reset(new pcl::PointCloud<PointXYZIR> (cloud_in));

    pcl::PointCloud<PointXYZIR>::Ptr cloudFiltered;
    cloudFiltered.reset(new pcl::PointCloud<PointXYZIR>);

    // Create the filtering object: downsample the dataset using a leaf size
    pcl::VoxelGrid<PointXYZIR> avg;
    avg.setInputCloud(cloudInput);
    avg.setLeafSize(0.25f, 0.25f, 0.25f);
    avg.filter(*cloudFiltered);

    //Filter object
    pcl::PassThrough<PointXYZIR> filter;
    filter.setInputCloud(cloudFiltered);

    filter.setFilterFieldName("x");
    filter.setFilterLimits(-100, 100);
    filter.filter(*cloudFiltered);

    filter.setFilterFieldName("y");
    filter.setFilterLimits(-100, 100);
    filter.filter(*cloudFiltered);

    cloud_out = *cloudFiltered;

2 个答案:

答案 0 :(得分:1)

体素网格到下采样应保持相当好的云分布,同时减少点数。您可以设置体素在每个轴上的小小,以便根据需要保持尽可能多的分辨率。每个体素将删除其中的所有点,并将其替换为单个点,该点与已删除的点平均。 http://pointclouds.org/documentation/tutorials/voxel_grid.php#voxelgrid

答案 1 :(得分:1)

实际上我确实找到了解决方案,但没有一般解决方案。在我的情况下,我认为这个问题非常具体,你会得到哪个点云以及你想用它做什么。

passtrought过滤器是一种非常有效的降低采样方式,而不会冒太多丢失有趣数据的风险。

  

http://pointclouds.org/documentation/tutorials/passthrough.php

然后我测试了StatisticalOutlierRemoval,效率很高但在我的情况下并不相关。

  

http://pointclouds.org/documentation/tutorials/statistical_outlier.php

现在,我使用leafsize函数对pointcloud进行下采样,然后创建一个kdtree来按半径过滤点。 它与passtrought过滤器的计算量相同,但在我的项目中以这种方式更有意义。

 // Create the filtering object: downsample the dataset using a leaf size
    pcl::VoxelGrid<PointXYZIR> avg;
    avg.setInputCloud(cloudInput);
    avg.setLeafSize(0.25f, 0.25f, 0.25f);
    avg.filter(*cloudFiltered);

    //searchPoint
    PointXYZIR searchPoint = cloudFiltered->at(0) ;

    //result from radiusSearch()
    std::vector<int> pointIdxRadiusSearch;
    std::vector<float> pointRadiusSquaredDistance;

    //kdTree
    pcl::KdTreeFLANN<PointXYZIR> kdtree;
    kdtree.setInputCloud (cloudFiltered);
    kdtree.setSortedResults(true);

    if ( kdtree.radiusSearch (searchPoint, 100, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 )
    {
        //delete every point in target
        for (size_t j = 0; j < pointIdxRadiusSearch.size (); ++j)
        {
            //is this the way to erase correctly???
            cloud_out.push_back(cloudFiltered->points[pointIdxRadiusSearch[j]]);
        }
    }