pcl拟合直线

#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/fuhong/Documents/github/pcl_realsenseSR300/data/xin_pcd/1/cut1.pcd",
                               *cloud);      //拟合相机倾斜拍照的点云
//    reader.read<pcl::PointXYZ>("/home/fuhong/kfr/kinect1_pcl/ground.pcd", *cloud);            //拟合近似垂直地面的点云
//    reader.read<pcl::PointXYZ>("/home/fuhong/kfr/kinect1_pcl/ground_final.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_LINE);  // Mandatory-设置目标几何形状
    seg.setMethodType(pcl::SAC_RANSAC);     //分割方法:随机采样法
    seg.setDistanceThreshold(0.001);         //设置误差容忍范围,也就是阈值
    seg.setInputCloud(cloud);               //输入点云
    seg.segment(*inliers, *coefficients);   //分割点云,获得平面和法向量
    //打印平面方程
    std::cout << "a:" << coefficients->values[0] << endl;
    std::cout << "b:" << coefficients->values[1] << endl;
    std::cout << "c:" << coefficients->values[2] << endl;
    std::cout << "d:" << coefficients->values[3] << endl;
    std::cout << "e:" << coefficients->values[4] << endl;
    std::cout << "f:" << coefficients->values[5] << 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_plane2(new pcl::PointCloud<pcl::PointXYZ>);  //存储平面点云
    pcl::ExtractIndices<pcl::PointXYZ> extract;  //创建点云提取对象
    extract.setInputCloud(cloud);    //设置输入点云
    extract.setIndices(inliers);     //设置分割后的内点为需要提取的点集
    extract.setNegative(false);      //false提取内点, true提取外点
    extract.filter(*c_plane2);        //提取输出存储到c_plane2


    // 点云可视化
    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");  // 设置点云大小
    pcl::io::savePCDFile("/home/fuhong/Documents/projects/realsenseSR300/data/realsense_sr300/model6.pcd", *c_plane2);
    viewer.spin();
}

参数说明:
用于确定线模型。线的六个系数由线上的点和线的方向给出:[ point_on_line.x point_on_line.y point_on_line.z line_direction.x line_direction.y line_direction.z ]
point_on_line.x :直线上一点的X坐标
point_on_line.y :直线上一点的Y坐标
point_on_line.z :直线上一点的Z坐标
line_direction.x :线方向的X坐标
line_direction.y :直线方向的Y坐标
line_direction.z :直线方向的Z坐标

发布了40 篇原创文章 · 获赞 3 · 访问量 1414

猜你喜欢

转载自blog.csdn.net/hongge_smile/article/details/104052070