PCL Prosac算法(拟合平面为例)(SampleConsensus_PROSAC)

PCL专栏目录及须知

本算法一般用在寻找最优模型上,最大迭代次数往往要设置较大。

PCL拟合模型方法效果对比
拟合方法用时样本点数拟合得出内点数拟合百分比平面方程参数
LMedS6.59863s342621588046.3487%A:-0.245971,B:0.328976,C:-0.911742,D:273.254
RMSAC40.2117s3426224187.05738%A:-0.14948,B:-0.570804,C:0.807365,D:-191.15
MSAC0.732149s342621455142.4698%A:-0.198437,B:0.323444,C:-0.925206,D:275.461
PROSAC0.0931069s342621362739.7729%A:0.256624,B:-0.288087,C:0.922578,D:-283.215
Ransac0.093296s342621487043.4009%A:-0.226923,B:0.322948,C:-0.918809,D:276.486
MLESAC4.8623s342621358039.487%A:-0.245971,B:0.328976,C:-0.911742,D:273.254

 本文以拟合平面为例子,如果使用其他模型:修改该处代码,按照下文其他例程使用即可。

其他模型拟合例程

PCL 拟合二维圆(以RANSAC为例)

PCL 拟合三维圆(以RANSAC为例)

PCL 拟合直线(以RANSAC为例)

PCL 拟合球体(以RANSAC为例)

PCL 拟合圆柱(以RANSAC为例)

PCL 拟合圆锥(以RANSAC为例)

1.Prosac 算法

(1)Prosac 算法是一种随机采样的RANSAC算法,用于解决拟合模型问题。

(2)核心思想:不断随机采样数据集,并在每次采样后计算型拟合误差,并根据误差来选择最优模型。

(3)优点:可以更快地找到最优模型,因为它能够在计算模型拟合误差的同时,随机采样数据集;

缺点:需要进行大量的计算和迭代,因此可能会有一定的运行时间。

(4)计算流程:

1)随机采样数据集。

2)计算模型拟合误差。

3)根据误差选择最优模型。

4)重复以上步骤直到达到预设的迭代次数或误差阀值。

2.完整代码

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/sample_consensus/prosac.h>
#include <pcl/sample_consensus/sac_model_plane.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
#include <pcl/console/time.h>

int main()
{
    /****************PROSAC拟合(以拟合平面为例)********************/
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);			// 源点云
    pcl::io::loadPCDFile("D:/code/csdn/data/samp11-TIN.pcd", *cloud);
    pcl::SampleConsensusModelPlane<pcl::PointXYZ>::Ptr modelPlane(new pcl::SampleConsensusModelPlane<pcl::PointXYZ>(cloud)); // 待拟合平面点云对象
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloudInliers(new pcl::PointCloud<pcl::PointXYZ>);			// 拟合出平面的内点

    // PROSAC
    pcl::console::TicToc time; time.tic();
    pcl::ProgressiveSampleConsensus<pcl::PointXYZ> PROSAC(modelPlane);                     // PROSAC算法模型
    PROSAC.setDistanceThreshold(3.0);                                                       // 距离阈值
    PROSAC.setMaxIterations(500);                                                           // 最大迭代次数
    PROSAC.computeModel();                                                                  // 拟合平面
    Eigen::VectorXf PROSACCof;
    PROSAC.getModelCoefficients(PROSACCof);                                                   // 获取模型参数
    std::vector<int> PROSACInliers;                                                         // 获取属于拟合出平面的内点
    PROSAC.getInliers(PROSACInliers);
    pcl::copyPointCloud(*cloud, PROSACInliers, *cloudInliers);

    std::cout << "PROSAC计算时间:" << time.toc() / 1000 << "s" << std::endl;
    std::cout << "PROSAC原始点数:" << cloud->size() << std::endl;
    std::cout << "PROSAC拟合点数:" << PROSACInliers.size() << std::endl;
    std::cout << "PROSAC拟合百分比:" << ((double)PROSACInliers.size() / (double)cloud->size()) * 100 << "%" << std::endl;
    std::cout << "PROSAC平面参数:" << "A:" << PROSACCof[0] << ",B:" << PROSACCof[1] << ",C:" << PROSACCof[2] << ",D:" << PROSACCof[3] << std::endl;

    /****************展示********************/
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("PROSAC"));
    viewer->addPointCloud<pcl::PointXYZ>(cloud, "cloud");
    viewer->addPointCloud<pcl::PointXYZ>(cloudInliers, pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloudInliers, 255, 0, 0), "cloudInliers");

    while (!viewer->wasStopped())
    {
        viewer->spinOnce(100);
        boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }

    return (0);
}

3.结果展示

打印:

可视化结果:

PCL(Point Cloud Library)是一个开源的点云处理库,其中包含了许多常用的点云处理算法平面拟合算法RANSAC。RANSAC(Random Sample Consensus)是一种用于估计模型参数的迭代方法,它可以在存在噪声和离群点的数据中找到最佳的模型参数。 下面我们来详细介绍一下PCL中的RANSAC算法平面拟合中的应用。 1. 原理 平面拟合是指在点云数据中找到最适合一组点集的平面方程。假设我们有一个点云数据集$P = \{p_1, p_2, ..., p_N\}$,其中每个点$p_i$都有三个坐标$(x_i, y_i, z_i)$。我们的目标是在其中找到一个平面方程$ax + by + cz + d = 0$,其中$a, b, c$是平面的法向量,$d$是平面到原点的距离。 PCL中的平面拟合算法RANSAC的基本思想是在数据集中随机选择一组点,然后计算这些点所代表的平面方程,将这个平面方程与其他点的距离进行比较,判断哪些点属于这个平面。如果有足够多的点属于这个平面,那么这个平面就是一个好的拟合。如果选择的点不够好,那么就重新随机选择一组点,直到找到一个好的拟合。 2. 算法流程 具体来说,PCL中的RANSAC算法流程如下: 1) 从点云数据集中随机选择$n$个点,这些点被称为内点(inliers)。 2) 计算这$n$个点所代表的平面方程。 3) 遍历数据集中的每个点,计算该点到平面的距离,如果距离小于一定的阈值,那么将该点标记为内点。如果内点的数目超过了一定比,那么就认为这$n$个点代表了一个好的拟合。 4) 重复上述步骤若干次,最终选择内点数目最多的平面方程作为最终的拟合结果。 3. 代码实现 下面是一个简单的PCL平面拟合的代码实现,其中使用了RANSAC算法: ```cpp #include <pcl/point_types.h> #include <pcl/features/normal_3d.h> #include <pcl/sample_consensus/method_types.h> #include <pcl/sample_consensus/model_types.h> #include <pcl/segmentation/sac_segmentation.h> int main() { // 定义点云数据 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); // 从文件中读取点云数据 pcl::io::loadPCDFile<pcl::PointXYZ>("table_scene_lms400.pcd", *cloud); // 创建分割对象 pcl::SACSegmentation<pcl::PointXYZ> seg; // 设置分割参数 seg.setOptimizeCoefficients(true); seg.setModelType(pcl::SACMODEL_PLANE); seg.setMethodType(pcl::SAC_RANSAC); seg.setMaxIterations(1000); seg.setDistanceThreshold(0.01); // 创建模型系数和点索引容器 pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients); pcl::PointIndices::Ptr inliers(new pcl::PointIndices); // 执行分割 seg.setInputCloud(cloud); seg.segment(*inliers, *coefficients); // 输出平面方程的系数 std::cerr << "Model coefficients: " << coefficients->values[0] << " " << coefficients->values[1] << " " << coefficients->values[2] << " " << coefficients->values[3] << std::endl; } ``` 其中,loadPCDFile函数用于读取点云数据,SACSegmentation对象用于进行平面拟合,setModelType和setMethodType用于设置平面模型和拟合方法,setMaxIterations设置迭代次数,setDistanceThreshold设置距离阈值。最后,segment函数执行拟合,并返回拟合结果的系数和内点索引。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值