点云拟合直线轨迹(CloudComapre+PCL)

该代码段展示了如何在Qt环境中,利用PCL库对点云数据进行处理,通过RANSAC算法进行直线拟合,并将结果在CloudCompare中显示。首先,从选定的点云实体中读取数据,然后进行空间直线拟合,计算出直线方程,并提取内点形成新的点云表示直线路径。最后,更新界面显示拟合结果。
摘要由CSDN通过智能技术生成
  1. ui添加

  1. 添加connect连接槽函数

connect(m_UI->actionLinePathFit, &QAction::triggered, this, &MainWindow::doActionLinePathFit);
  1. 添加函数声明

void doActionLinePathFit(); //直线轨迹
  1. 添加PCL头文件

#include <pcl/keypoints/uniform_sampling.h>            // 均匀采样
#include <pcl/sample_consensus/ransac.h>            //随机采样一致性算法实现
#include <pcl/sample_consensus/sac_model_line.h>    //直线采样
  1. 添加函数实现

void MainWindow::doActionLinePathFit()
{
    if (getSelectedEntities().size() != 1)
    {
        ccLog::Print(QStringLiteral("只能选择一个点云实体"));
        return;
    }
    ccHObject* entity = getSelectedEntities()[0];
    ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);
    // ---------------------------读取数据到PCL----------------------------------
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    cloud->resize(ccCloud->size());
    for (int i = 0; i < cloud->size(); ++i)
    {
        const CCVector3* point = ccCloud->getPoint(i);
        cloud->points[i].x = point->x;
        cloud->points[i].y = point->y;
        cloud->points[i].z = point->z;
    }


    //----------------------------- 空间直线拟合 -----------------------------
    pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model_line(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud));    //指定拟合点云与几何模型
    pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_line);    //创建随机采样一致性对象
    ransac.setDistanceThreshold(1);    //设置容忍范围,也就是阈值
    ransac.setMaxIterations(10000);        //最大迭代次数
    ransac.computeModel();                //执行RANSAC空间直线拟合

    vector<int> inliers;                //存储内点索引的向量
    ransac.getInliers(inliers);            //提取内点对应的索引

    /// 根据索引提取内点
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *cloud_line);

    /// 模型参数
    Eigen::VectorXf coefficient;
    ransac.getModelCoefficients(coefficient);

    ccLog::Print(QStringLiteral("直线点向式方程为\n(x -%1) / %2 = (y - %3) / %4 = (z - %5) / %6").arg(coefficient[0]).arg(coefficient[1]).arg(coefficient[2]).arg(coefficient[3]).arg(coefficient[4]).arg(coefficient[5]));

    // ------------------------PCL->CloudCompare--------------------------------
    if (!cloud_line->empty())
    {
        ccPointCloud* Path = new ccPointCloud(QString("Path"));
        for (int i = 0; i < cloud_line->size(); ++i)
        {
            double x = cloud_line->points[i].x;
            double y = cloud_line->points[i].y;
            double z = cloud_line->points[i].z;
            Path->addPoint(CCVector3(x, y, z));
        }
        Path->setColor(ccColor::Rgba(rand() % 255, rand() % 255, 0, 255));
        Path->showColors(true);
        if (ccCloud->getParent())
        {
            ccCloud->getParent()->addChild(Path);
        }
        ccCloud->setEnabled(false);
        addToDB(Path);


        ccPointCloud* PointCloudafterPCL = new ccPointCloud(QString("PCL计算后的点云"));
        for (int i = 0; i < cloud->size(); ++i)
        {
            double x = cloud->points[i].x;
            double y = cloud->points[i].y;
            double z = cloud->points[i].z;
            PointCloudafterPCL->addPoint(CCVector3(x, y, z));
        }
        PointCloudafterPCL->setColor(ccColor::Rgba(rand() % 255, rand() % 255, 0, 255));
        PointCloudafterPCL->showColors(true);
        if (ccCloud->getParent())
        {
            ccCloud->getParent()->addChild(PointCloudafterPCL);
        }
        ccCloud->setEnabled(false);
        addToDB(PointCloudafterPCL);



        refreshAll();
        updateUI();
    }
    else
    {
        ccCloud->setEnabled(true);
        // Display a warning message in the console
        dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);
    }

}

结果显示1

主视图

左视图

显示结果2

主视图

左视图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值