pcl实现Delaunay三角剖分重建网格

1.下采样
通常点云三角化算法计算量非常大,如果输入大量点云的话,运行时间可能会需要数十分钟甚至数个小时,因此,点云处理的第一步便是下采样。

//下采样
void downsampledPointcloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud)
{
	// 下采样
    pcl::VoxelGrid<PointT> downSampled;  //创建滤波对象
    downSampled.setInputCloud (cloud);            //设置需要过滤的点云给滤波对象
    downSampled.setLeafSize (0.01f, 0.01f, 0.01f);  //设置滤波时创建的体素体积为1cm的立方体
    downSampled.filter (*cloud_downSampled);           //执行滤波处理,存储输出
    pcl::io::savePCDFile ("downsampledPC.pcd", *cloud_downSampled);
}

2.去除离群点(滤波)

//统计滤波
void statisOutlierRemoval(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_downSampled)
{
	// 统计滤波
    pcl::StatisticalOutlierRemoval<PointT> statisOutlierRemoval;       //创建滤波器对象
    statisOutlierRemoval.setInputCloud (cloud_downSampled);            //设置待滤波的点云
    statisOutlierRemoval.setMeanK (50);                                //设置在进行统计时考虑查询点临近点数
    statisOutlierRemoval.setStddevMulThresh (3.0);                     //设置判断是否为离群点的阀值:均值+1.0*标准差
    statisOutlierRemoval.filter (*cloud_filtered);                     //滤波结果存储到cloud_filtered
    pcl::io::savePCDFile ("filteredPC.pcd", *cloud_filtered);
}

3.点云平滑

//重采样平滑点云
void SmoothPointcloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_in, pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud_out)
{
	// 对点云重采样  
    pcl::search::KdTree<PointT>::Ptr treeSampling (new pcl::search::KdTree<PointT>);// 创建用于最近邻搜索的KD-Tree
    pcl::PointCloud<PointT> mls_point;    //输出MLS
    pcl::MovingLeastSquares<PointT,PointT> mls; // 定义最小二乘实现的对象mls
    mls.setComputeNormals(false);  //设置在最小二乘计算中是否需要存储计算的法线
    mls.setInputCloud(cloud_filtered);         //设置待处理点云
    mls.setPolynomialOrder(2);            // 拟合2阶多项式拟合
    mls.setPolynomialFit(false);     // 设置为false可以 加速 smooth
    mls.setSearchMethod(treeSampling);         // 设置KD-Tree作为搜索方法
    mls.setSearchRadius(0.05);           // 单位m.设置用于拟合的K近邻半径
    mls.process(mls_point);                 //输出
    // 输出重采样结果
    cloud_smoothed = mls_point.makeShared();
    std::cout<<"cloud_smoothed: "<<cloud_smoothed->size() <<std::endl;
    //save cloud_smoothed
    pcl::io::savePCDFileASCII("cloud_smoothed.pcd",*cloud_smoothed);
}

4.点云的法向量计算

//计算法线
pcl::PointCloud<pcl::Normal>::Ptr CalculateNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud_in)
{
	// 法线估计
    pcl::NormalEstimation<PointT,pcl::Normal> normalEstimation;             //创建法线估计的对象
    normalEstimation.setInputCloud(cloud_smoothed);                         //输入点云
    pcl::search::KdTree<PointT>::Ptr tree(new pcl::search::KdTree<PointT>);// 创建用于最近邻搜索的KD-Tree
    normalEstimation.setSearchMethod(tree);
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); // 定义输出的点云法线
    // K近邻确定方法,使用k个最近点,或者确定一个以r为半径的圆内的点集来确定都可以,两者选1即可
    normalEstimation.setKSearch(10);// 使用当前点周围最近的10个点
    //normalEstimation.setRadiusSearch(0.03);            //对于每一个点都用半径为3cm的近邻搜索方式
    normalEstimation.compute(*normals);               //计算法线
    // 输出法线
    std::cout<<"normals: "<<normals->size()<<", "<<"normals fields: "<<pcl::getFieldsList(*normals)<<std::endl;
    pcl::io::savePCDFileASCII("normals.pcd",*normals);
}

5.贪心三角化算法得到Mesh

//计算法线
pcl::PointCloud<pcl::Normal>::Ptr CalculateNormal(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud_in)
{
	 // 三角化
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;   // 定义三角化对象
    pcl::PolygonMesh triangles; //存储最终三角化的网络模型

    // 设置三角化参数
    gp3.setSearchRadius(0.1);  //设置搜索时的半径,也就是KNN的球半径
    gp3.setMu (2.5);  //设置样本点搜索其近邻点的最远距离为2.5倍(典型值2.5-3),这样使得算法自适应点云密度的变化
    gp3.setMaximumNearestNeighbors (100);    //设置样本点最多可搜索的邻域个数,典型值是50-100

    gp3.setMinimumAngle(M_PI/18); // 设置三角化后得到的三角形内角的最小的角度为10°
    gp3.setMaximumAngle(2*M_PI/3); // 设置三角化后得到的三角形内角的最大角度为120°

    gp3.setMaximumSurfaceAngle(M_PI/4); // 设置某点法线方向偏离样本点法线的最大角度45°,如果超过,连接时不考虑该点
    gp3.setNormalConsistency(false);  //设置该参数为true保证法线朝向一致,设置为false的话不会进行法线一致性检查

    gp3.setInputCloud (cloud_with_normals);     //设置输入点云为有向点云
    gp3.setSearchMethod (tree2);   //设置搜索方式
    gp3.reconstruct (triangles);  //重建提取三角化

    // 显示网格化结果
    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer->setBackgroundColor(0, 0, 0);  //
    viewer->addPolygonMesh(triangles, "wangge");  //
    while (!viewer->wasStopped())
    {
    	viewer->spinOnce(100);
    	boost::this_thread::sleep(boost::posix_time::microseconds(100000));
    }
    return 1;}

https://gitee.com/junhaowu/pcl-mesh-reconstruction/tree/master源码

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值