PCL点云滤波:直通滤波PassThrough(简单卡阈值留点)和适用场景

目录

PCL直通滤波使用和点云打印

直通滤波的原理

直通滤波的使用场景和使用体验


PCL直通滤波使用和点云打印

除了对PCL直通滤波的常用基本功能实现,具体看注释。

说明了多维度直通滤波的用法,即卡多个阈值得到点云结果,例如PointXYZ,对“x” “y” 三个值都需要卡阈值时的使用方法;

/*20201022 by 手口一斤*/
#include <iostream>
#include <ctime>
#include <pcl/point_types.h>
#include <pcl/filters/passthrough.h>
int
testfilters_passthrough(int argc, char** argv)
{
    srand(time(0));
    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_filtered_xz(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered_xyz(new pcl::PointCloud<pcl::PointXYZ>);
    //填入点云数据
    cloud->width = 10;
    cloud->height = 1;
    cloud->points.resize(cloud->width * cloud->height);
    for (size_t i = 0; i < cloud->points.size(); ++i)
    {
        cloud->points[i].x = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].y = rand() / (RAND_MAX + 1.0f) - 0.5;
        cloud->points[i].z = rand() / (RAND_MAX + 1.0f) - 0.5;
    }
    std::cerr << "Cloud before filtering: " << std::endl;
    for (size_t i = 0; i < cloud->points.size(); ++i)
        std::cerr << "    " << cloud->points[i].x << " "
        << cloud->points[i].y << " "
        << cloud->points[i].z << std::endl;
    // 创建滤波器对象,第一次对Z卡阈值
    pcl::PassThrough<pcl::PointXYZ> pass(true);
    pass.setInputCloud(cloud);
    pass.setFilterFieldName("z"); //通过z滤波
    pass.setFilterLimits(0.0, 1.0);
    pass.setNegative (true);//设置为true,则输出范围外的点
    pass.filter(*cloud_filtered);

    // 第二次对X卡阈值滤波
    pcl::IndicesConstPtr cloud_filtered_other = pass.getRemovedIndices();//获取上一步剩下的点,即cloud_filtered以外的点
    pass.setIndices(cloud_filtered_other); //对cloud_filtered_other中的点进行滤波处理
    pass.setFilterFieldName("x");
    pass.setFilterLimits(0.0, 1.0);
    pass.setNegative(false);
    pass.filter(*cloud_filtered_xz);

    //这样滤波也能成功,但是结果不对,所以想多次滤波还是按照上面的方式
    //pass.setInputCloud(cloud_filtered_xz);
    //pass.setFilterFieldName("y");
    //pass.setFilterLimits(-1.0,0.0);
    //pass.filter(*cloud_filtered_xyz);


    std::cerr << "Cloud after filtering: " << std::endl;
    for (size_t i = 0; i < cloud_filtered->points.size(); ++i)
        std::cerr << "    " << cloud_filtered->points[i].x << " "
        << cloud_filtered->points[i].y << " "
        << cloud_filtered->points[i].z << std::endl;
    std::cerr << "Cloud after filtering2: " << std::endl;
    for (size_t i = 0; i < cloud_filtered_xz->points.size(); ++i)
        std::cerr << "    " << cloud_filtered_xz->points[i].x << " "
        << cloud_filtered_xz->points[i].y << " "
        << cloud_filtered_xz->points[i].z << std::endl;
    //std::cerr << "Cloud after filtering3: " << std::endl;
    //for (size_t i = 0; i < cloud_filtered_xyz->points.size(); ++i)
    //    std::cerr << "    " << cloud_filtered_xyz->points[i].x << " "
    //    << cloud_filtered_xyz->points[i].y << " "
    //    << cloud_filtered_xyz->points[i].z << std::endl;
    //return (0);
}

运行结果

点的数值不一样,因为可能是随机生成的

直通滤波的原理

先规定要卡值的对象,例如X,Y,Z,I,R,G,B等,取得或者去掉某一个值范围外的点集;

直通滤波的使用场景和使用体验

卡出或者卡掉某一个维度取值在一定范围内的点,适合点云初步卡ROI区域;

适合点云分布较分散的情况,根据某一些值可得到目标点云;

适合简单卡掉或者卡出异常值;

运算速度比较快,适合大点云小点云卡范围;

不适合卡出非常复杂的范围的情况,不好验证;

参考:https://pcl.readthedocs.io/projects/tutorials/en/latest/passthrough.html#passthrough

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值