pcl RANSAC平面分割 单帧激光点云地面提取

本文介绍了一种使用RANSAC算法在ROS环境下从Velodyne激光雷达单帧点云中快速提取地面点的方法。该方法通过设置Z轴阈值并结合RANSAC平面拟合技术实现地面点云的增量式提取。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

介绍

ros下velodyne激光雷达的回调函数, 利用RANSAC平面分割, 从单帧激光点云中提取出地面点

该方法可用于incremental的地面提取, 优势是速度快;
但由于地面并不总是平面, 所以该方法不如batch方法, 但batch方法要对全部激光点云进行计算, 速度较慢.

代码

void vldHandle(const sensor_msgs::PointCloud2ConstPtr &laserCloudMsg)
{
    double timeCur = laserCloudMsg->header.stamp.toSec();
    time_now = timeCur;
    pcl::PointCloud<PointType>::Ptr laserCloudIn;
    laserCloudIn.reset(new pcl::PointCloud<PointType>());
    pcl::fromROSMsg(*laserCloudMsg, *laserCloudIn);
    // Remove Nan points
    std::vector<int> indices;
    pcl::removeNaNFromPointCloud(*laserCloudIn, *laserCloudIn, indices);

    pcl::PointCloud<PointType>::Ptr ground_cloud, ground_cloud_candidate;
    ground_cloud.reset(new pcl::PointCloud<PointType>());
    ground_cloud_candidate.reset(new pcl::PointCloud<PointType>());
    pcl::PassThrough<PointType> pass;
    pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
    pcl::SACSegmentation<PointType> seg;
    pcl::ExtractIndices<PointType> extract;

    // 初始化RANSAC分割器
    seg.setOptimizeCoefficients(true);
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setDistanceThreshold(ground_RANSAC_threshold);
    //seg.setAxis(Eigen::Vector3f(0, 0, 1.0));

    // 提取地面点
    pass.setInputCloud(laserCloudIn);
    pass.setFilterFieldName("z");
    pass.setFilterLimits(ground_lower_threshold - sensorMountHeight, ground_upper_threshold - sensorMountHeight);
    pass.filter(*ground_cloud_candidate);

    seg.setOptimizeCoefficients(true);
    seg.setModelType(pcl::SACMODEL_PLANE);
    seg.setMethodType(pcl::SAC_RANSAC);
    seg.setDistanceThreshold(0.1);

    seg.setInputCloud(ground_cloud_candidate);
    seg.segment(*inliers, *coefficients);

    extract.setInputCloud(ground_cloud_candidate);
    extract.setIndices(inliers);
    extract.setNegative(false);
    extract.filter(*ground_cloud);

    if(ground_cloud_time_que.size() == 0 || ground_cloud_time_que.back() != timeCur)
    {
        //increaseGroundCloud(ground_cloud);
        ground_cloud_que.push(ground_cloud);
        ground_cloud_time_que.push(timeCur);
        ground_cloud_current.reset(new pcl::PointCloud<PointType>());
        *ground_cloud_current += *ground_cloud;
    }

    if(obstacle_cloud_time_que.size() == 0 || obstacle_cloud_time_que.back() != timeCur)
    {
        obstacle_cloud_que.push(laserCloudIn);
        obstacle_cloud_time_que.push(timeCur);
        obstacle_cloud_current.reset(new pcl::PointCloud<PointType>());
        *obstacle_cloud_current += *laserCloudIn;
    }
    //cout<<"receive vld, time: "<<setprecision(14)<<timeCur<<endl;
}

其中的部分全局变量

pcl::PointCloud<PointType>::Ptr ground_cloud_current; // 当前帧地面点云
pcl::PointCloud<PointType>::Ptr obstacle_cloud_current; // 当前帧全部点云
queue<pcl::PointCloud<PointType>::Ptr> ground_cloud_que; // 存放地面点云的queue
queue<double> ground_cloud_time_que; // 存放地面点云time_stamp的queue

queue<pcl::PointCloud<PointType>::Ptr> obstacle_cloud_que; // 存放全部点云的queue
queue<double> obstacle_cloud_time_que; // 存放全部点云time_stamp读queue
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值