欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PCL点云 RANSAC分割平面,提取子集

程序员文章站 2024-03-25 10:45:28
...

点云平面分割,并渲染平面点

#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/progressive_morphological_filter.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/visualization/cloud_viewer.h>

int main() {

    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PointIndicesPtr ground (new pcl::PointIndices);

    // 填入点云数据
    pcl::PCDReader reader;
    // 把路径改为自己存放文件的路径
    reader.read<pcl::PointXYZ> ("/home/lp01/workspace/filename.pcd", *cloud);
    std::cerr << "Cloud before filtering: " << std::endl;
    std::cerr << *cloud << std::endl;


    //创建一个模型参数对象,用于记录结果
    pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients);
    pcl::PointIndices::Ptr inliers(new pcl::PointIndices);  //inliers表示误差能容忍的点 记录的是点云的序号
    pcl::SACSegmentation<pcl::PointXYZ> seg;     // 创建一个分割器
    seg.setOptimizeCoefficients(true);      // Optional,这个设置可以选定结果平面展示的点是分割掉的点还是分割剩下的点。
    seg.setModelType(pcl::SACMODEL_PLANE);  // Mandatory-设置目标几何形状
    seg.setMethodType(pcl::SAC_RANSAC);     //分割方法:随机采样法
    seg.setDistanceThreshold(0.05);         //设置误差容忍范围,也就是我说过的阈值
    seg.setInputCloud(cloud);               //输入点云
    seg.segment(*inliers, *coefficients);   //分割点云,获得平面和法向量
    //打印出法向量
    std::cout << "x:" << coefficients->values[0] << endl;
    std::cout << "y:" << coefficients->values[1] << endl;
    std::cout << "z:" << coefficients->values[2] << endl;

    /*子集提取*/
    //平面点获取
    pcl::PointCloud<pcl::PointXYZ>::Ptr c_plane(new pcl::PointCloud<pcl::PointXYZ>);
    for (int i = 0; i < inliers->indices.size(); ++i)
    {
        c_plane->points.push_back(cloud->points.at(inliers->indices[i]));
    }

    /*单个平面时*/
    //平面点获取
    pcl::PointCloud<pcl::PointXYZ>::Ptr c_plane (new pcl::PointCloud<pcl::PointXYZ>);  //存储平面点云
    pcl::ExtractIndices<pcl::PointXYZ> extract;  //创建点云提取对象
    extract.setInputCloud (cloud);    //设置输入点云
    extract.setIndices (inliers);     //设置分割后的内点为需要提取的点集
    extract.setNegative (false);      //false提取内点, true提取外点
    extract.filter (*c_plane);        //提取输出存储到c_plane


    // 点云可视化
    pcl::visualization::PCLVisualizer viewer;
    viewer.addPointCloud(cloud, "cloud");  // 加载比对点云

    pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> c_plane_color(c_plane, 255, 0,
                                                                                  0);  // 设置点云颜色
    viewer.addPointCloud(c_plane, c_plane_color, "c_plane");  // 加载凹凸点云
    viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1,
                                            "c_plane");  // 设置点云大小

    viewer.spin();
}