PCL库学习(3)----基于平面模型的点云分割(地面点云分割)(Plane Model Segmentation)


运行环境:

VS2013,PCL1.8.0

代码参考:

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


       最近做的项目需要对采集到的点云场景进行去除地面的操作。在参考了CSDN博主:有梦想的田园犬对于PCL官方几种例程中的点云分割方法的实验后,考虑到系统的实时性要求,选择基于平面模型的地面点云去噪方法。

 

1、算法细节

       该方法是利用RANSAC去找到点云中的平面,简单总结RANSAC的原理:通过随机采样,只利用有效的数据实现最优的拟合效果(如有不对望指正)。具体的原理可以参考随机抽样一致算法(Random sample consensus,RANSAC)。

 

2、调参

       这个方法需要调节的参数就只有一个,setDistanceThreshold,距离阈值(PCL中单位为m)。距离阈值越大,离平面越远的点也被算作平面的组成。

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
    viewer.setBackgroundColor(0,0,1);
}

int
 main (int argc, char** argv)
{
    pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
    pcl::PointCloud::Ptr cloud_filtered(new pcl::PointCloud);
    pcl::PCDReader reader;
    // 读入点云PCD文件
    reader.read("3dpoints.pcd",*cloud);

    std::cerr << "Point cloud data: " << cloud->points.size () << " points" << std::endl;
    
    pcl::ModelCoefficients::Ptr coefficients (new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliers (new pcl::PointIndices);
    // Create the segmentation object
    pcl::SACSegmentation seg;
    // Optional
    seg.setOptimizeCoefficients (true);
    // Mandatory
    seg.setModelType (pcl::SACMODEL_PLANE);
    seg.setMethodType (pcl::SAC_RANSAC);
    // 距离阈值 单位m
    seg.setDistanceThreshold (0.15);
    seg.setInputCloud (cloud);
    seg.segment (*inliers, *coefficients);
    if (inliers->indices.size () == 0)
    {
        PCL_ERROR ("Could not estimate a planar model for the given dataset.");
        return (-1);
    }


    // 提取地面
    pcl::ExtractIndices extract;
    extract.setInputCloud (cloud);
    extract.setIndices (inliers);
    extract.filter (*cloud_filtered);

    std::cerr << "Ground cloud after filtering: " << std::endl;
    std::cerr << *cloud_filtered << std::endl;

    pcl::PCDWriter writer;
    writer.write ("3dpoints_ground.pcd", *cloud_filtered, false);

    // 提取除地面外的物体
    extract.setNegative (true);
    extract.filter (*cloud_filtered);

    std::cerr << "Object cloud after filtering: " << std::endl;
    std::cerr << *cloud_filtered << std::endl;

    writer.write ("3dpoints_object.pcd", *cloud_filtered, false);

    // 点云可视化
    pcl::visualization::CloudViewer viewer("Filtered");
    viewer.showCloud(cloud_filtered);
    viewer.runOnVisualizationThreadOnce(viewerOneOff);
    while(!viewer.wasStopped()){
    
    }
    return (0);
}

 

3、实验结果

留个坑,回学校填上

你可能感兴趣的:(Point,Cloud,Library,(PCL))