本站使用了 Pjax 等基于 JavaScript 的开发技术,但您的浏览器已禁用 JavaScript,请开启 JavaScript 以保证网站正常显示!

PCL直通滤波

PCL库实现了多种点云的滤波方法,直通滤波(passthrough filter)为众多滤波方法里面比较基础简单的滤波方法。直通滤波原理非常简单,顾名思义也能猜出其滤波的方法流程,"直通"即基于点云空间坐标系设定一个通道,将点云在通道范围之外的点剔除滤掉从而保留通道里边的点云。这个"通道"在PCL里面具体表现为针对某个坐标轴设定的限定范围,比如:

setFilterFieldName("z");
setFilterLimits(0.0f, 1.0f);

以上滤波只保留点云z轴范围在[0.0, 1.0]之内的点云

setFilterFieldName("x");
setFilterLimits(-2.0f, 3.0f);

则滤波只保留点云x轴范围在[-2.0, 3.0]之内的点云。其原理非常简单,下面直接贴出使用示例代码

#include <iostream>
#include <random>

#include "pcl/point_types.h"
#include "pcl/filters/passthrough.h"
#include "pcl/visualization/pcl_visualizer.h"

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::PointCloud<pcl::PointXYZ>::Ptr cloud_removed(new pcl::PointCloud<pcl::PointXYZ>);

    //step1: 创建点云数据
    std::random_device rd;
    std::default_random_engine random(rd());
    std::uniform_real_distribution<float> dis(0.0f, 3.0f);

    for(int i = 0; i < 3000; ++i)
    {
        float x =  dis(random);
        float y =  dis(random);
        float z =  dis(random);
        cloud->points.push_back({x, y, z});
    }
    
    //step2: 创建直通滤波对象
    pcl::PassThrough<pcl::PointXYZ> pass_through_filter;

    //step3: 设置直通滤波参数
    pass_through_filter.setInputCloud(cloud);
    pass_through_filter.setFilterFieldName("z");
    pass_through_filter.setFilterLimits(0.0f, 1.0f);

    //step4: 执行滤波处理
    pass_through_filter.filter(*cloud_filtered);

    //step5: 可视化滤波结果

    pass_through_filter.setFilterLimits(1.0f, 3.0f);//重新滤波,提取第一次滤波剔除的部分点云
    pass_through_filter.filter(*cloud_removed);

    pcl::visualization::PCLVisualizer viewer("pcl pass throuhg filter");
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handler(cloud_removed, 255, 0, 0);
    viewer.addPointCloud(cloud_removed, cloud_handler, "cloud_removed");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_handler(cloud_filtered , 0, 255, 0);
    viewer.addPointCloud(cloud_filtered, filtered_handler, "cloud_filtered");

    viewer.addCoordinateSystem(1);

    while (!viewer.wasStopped()) 
    {
        viewer.spinOnce();
    }
    viewer.close();

    return 0;
}

执行程序的结果如图

pcl-passthrough-filter.png
坐标轴xyz顺序是rgb颜色排序的,从蓝色z轴划分,绿色为第一遍[0,1]的滤波结果,红色则是为[1, 3]滤波结果

若是想要保留通道之外的点云,不想要限定坐标轴之内的点云,PCL提供了一整个设置取反的参数,只需要在滤波之前添加一行代码即可

pass_through_filter.setFilterLimitsNegative(false);

取反测试示例完整代码

#include <iostream>
#include <random>

#include "pcl/point_types.h"
#include "pcl/filters/passthrough.h"
#include "pcl/visualization/pcl_visualizer.h"

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::PointCloud<pcl::PointXYZ>::Ptr cloud_removed(new pcl::PointCloud<pcl::PointXYZ>);

    //step1: 创建点云数据
    std::random_device rd;
    std::default_random_engine random(rd());
    std::uniform_real_distribution<float> dis(0.0f, 3.0f);

    for(int i = 0; i < 3000; ++i)
    {
        float x =  dis(random);
        float y =  dis(random);
        float z =  dis(random);
        cloud->points.push_back({x, y, z});
    }
    
    //step2: 创建直通滤波对象
    pcl::PassThrough<pcl::PointXYZ> pass_through_filter;

    //step3: 设置直通滤波参数
    pass_through_filter.setInputCloud(cloud);
    //设置取反标志
    pass_through_filter.setFilterLimitsNegative(true);

    pass_through_filter.setFilterFieldName("z");
    pass_through_filter.setFilterLimits(0.0f, 1.0f);

    //step4: 执行滤波处理
    pass_through_filter.filter(*cloud_filtered);

    //step5: 可视化滤波结果

    pass_through_filter.setFilterLimits(1.0f, 3.0f);//重新滤波,提取第一次滤波剔除的部分点云
    pass_through_filter.filter(*cloud_removed);


    pcl::visualization::PCLVisualizer viewer("pcl pass throuhg filter");
    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_handler(cloud_removed, 255, 0, 0);
    viewer.addPointCloud(cloud_removed, cloud_handler, "cloud_removed");

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> filtered_handler(cloud_filtered , 0, 255, 0);
    viewer.addPointCloud(cloud_filtered, filtered_handler, "cloud_filtered");

    viewer.addCoordinateSystem(1);

    while (!viewer.wasStopped()) 
    {
        viewer.spinOnce();
    }
    viewer.close();

    return 0;
}

执行代码结果如下

pcl-passthrough-filter-negative.png
可以看到与先前滤波相比,红蓝点云位置置反了。


本文由芒果浩明发布,转载请注明出处。
本文链接:https://mangoroom.cn/algorithm/passthrough-filter-of-pcl.html


 继续浏览关于 滤波pcl直通滤波 的文章

 本文最后更新于:2020/09/28 18:13:49,可能因经年累月而与现状有所差异

 引用转载请注明:芒果的Blog > 算法,PCL > PCL直通滤波