基于PCL三维曲面重建

前言

曲面重建可以用于逆向工程、数据可视化、自动化建模等领域。本文希望能够将曲面重建运用在点云分割后的显示上,以增强点云分割后的可视化效果。
PCL中目前实现了多种基于点云的曲面重建算法,如:泊松曲面重建、贪婪投影三角化、移动立方体、EarClipping等算法。下面我将对泊松曲面重建算法和贪婪投影三角化算法进行介绍,具体算法的原理这里就不过多介绍了,只将代码和实验效果贴出共大家交流学习。
代码来源:这里写链接内容
http://pointclouds.org/documentation/tutorials/greedy_projection.php#greedy-triangulation

贪婪投影三角化算法

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/features/normal_3d.h>
#include <pcl/surface/gp3.h>
#include <pcl/visualization/pcl_visualizer.h>

int
main(/*int argc, char** argv*/)
{
    // Load input file into a PointCloud<T> with an appropriate type
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::PCLPointCloud2 cloud_blob;
    pcl::io::loadPCDFile("bun0.pcd", cloud_blob);
    pcl::fromPCLPointCloud2(cloud_blob, *cloud);
    //* the data should be available in cloud

    // Normal estimation*
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;
    pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
    pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
    tree->setInputCloud(cloud);
    n.setInputCloud(cloud);
    n.setSearchMethod(tree);
    n.setKSearch(20);
    n.compute(*normals);
    //* normals should not contain the point normals + surface curvatures

    // Concatenate the XYZ and normal fields*
    pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
    pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
    //* cloud_with_normals = cloud + normals

    // Create search tree*
    pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
    tree2->setInputCloud(cloud_with_normals);

    // Initialize objects
    pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
    pcl::PolygonMesh triangles;

    // Set the maximum distance between connected points (maximum edge length)
    gp3.setSearchRadius(0.025);

    // Set typical values for the parameters
    gp3.setMu(2.5);
    gp3.setMaximumNearestNeighbors(100);
    gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees
    gp3.setMinimumAngle(M_PI / 18); // 10 degrees
    gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
    gp3.setNormalConsistency(false);

    // Get result
    gp3.setInputCloud(cloud_with_normals);
    gp3.setSearchMethod(tree2);
    gp3.reconstruct(triangles);

    // Additional vertex information
    std::vector<int> parts = gp3.getPartIDs();
    std::vector<int> states = gp3.getPointStates();

    boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
    viewer->setBackgroundColor(0, 0, 0);

    viewer->addPolygonMesh(triangles, "triangles");

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


    // Finish
    return (0);
}

如果想要只显示三角化后的网格,添加下面代码:

viewer->addPolylineFromPolygonMesh(triangles);

这里写图片描述
只显示三角网:
这里写图片描述

泊松曲面重建算法

    pcl::Poisson<pcl::PointNormal> pn;
    pn.setConfidence(false);
    pn.setDegree(2);
    pn.setDepth(8);
    pn.setIsoDivide(8);
    pn.setManifold(false);
    pn.setOutputPolygons(false);
    pn.setSamplesPerNode(3.0);
    pn.setScale(1.25);
    pn.setSolverDivide(8);
    pn.setSearchMethod(tree2);
    pn.setInputCloud(cloud_with_normals);
    pcl::PolygonMesh mesh;
    pn.performReconstruction(mesh);

这里写图片描述
只显示三角网:
这里写图片描述

### 泊松三维曲面重建算法概述 泊松三维曲面重建(Poisson Surface Reconstruction)是一种通过云数据生成连续表面的方法。该算法的核心思想是将输入的带法向量的视为采样自某个隐式函数的零等值面,并利用最小二乘优化来求解这个隐式函数[^1]。 #### 算法原理 泊松重建假设给定的集及其对应的法线方向可以表示为一个标量场 \( f(x) \),其中 \( f(x) = 0 \) 定义了目标表面。为了找到这样的标量场,算法构建了一个偏微分方程: \[ \nabla f = N, \] 这里 \( N \) 是由输入的法线组成的矢量场。通过对上述方程进行离化并应用有限差分方法,最终得到一个稀疏线性系统,可以通过共轭梯度法或其他数值技术高效求解[^1]。 #### 实现细节 实际实现过程中,通常采用八叉树结构加速计算过程中的空间划分操作。具体来说,八叉树不仅用于存储的位置信息,还帮助控制网格分辨率以及减少不必要的内存消耗。此外,在解决大规模线性系统的背景下,预条件子的选择对于提升收敛速度至关重要[^2]。 下面展示了一种简单的伪代码描述如何基于现有库执行泊松重建: ```cpp #include <pcl/surface/poisson.h> void poisson_reconstruction(pcl::PointCloud<pcl::PointXYZ>::Ptr &input_cloud, pcl::PolygonMesh &output_mesh){ pcl::surface::Poisson<pcl::PointXYZ> poisson; poisson.setDepth(9); // 设置最大深度 poisson.setInputCloud(input_cloud); poisson.reconstruct(output_mesh); } ``` 此片段依赖于Point Cloud Library(PCL),它提供了丰富的工具支持各种类型的几何处理任务,包括但不限于滤波、分割和平滑等功能模块[^5]。 ### 注意事项 尽管泊松重建能够生成高质量的结果,但在某些情况下可能会遇到挑战,比如当存在噪声或者不完整的扫描数据时。因此,在应用之前可能需要先对原始数据做适当清理工作,例如估计缺失的法线或是移除异常值等等[^3]。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值