赞
踩
今天对pcl库中surface模块的demo3代码进行了学习,现在记录一下其注释版本。
Fast triangulation of unordered point clouds
无序点云的快速三角剖分(pcl中的此类处理的点云数据须有法线,因此先需进行法线估计)
- #include <pcl/point_types.h>
- #include <pcl/io/pcd_io.h>
- #include <pcl/search/kdtree.h> // for KdTree
- #include <pcl/features/normal_3d.h>
- #include <pcl/surface/gp3.h>
- //包含头文件
-
- int main ()
- {
- // Load input file into a PointCloud<T> with an appropriate type
- //以适当的类型将输入文件加载到点云中
- pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
- //通过源码知:using pcl::PointCloud<PointT>::Ptr = shared_ptr<PointCloud<PointT>>
- //这里的Ptr其实是C++中的智能指针,所以我们只看到cloud的创建部分而通常没有cloud的delete部分。C++中智能指针写法:shared_ptr<T> myptr (new T);
- 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>);//定义kd树指针
- tree->setInputCloud (cloud);//用点云cloud构建tree对象
- n.setInputCloud (cloud);//为法线估计对象设置输入点云cloud
- n.setSearchMethod (tree);//设置搜索方法
- n.setKSearch (20);//设置k搜索的k值为20
- n.compute (*normals);//估计法线结果存储至normals中
- //* normals should not contain the point normals + surface curvatures
- //Normals中不应包含点法线+曲面曲率
-
- // Concatenate the XYZ and normal fields*连接XYZ和法线字段
- //由于XYZ坐标字段与法线字段需要在相同的PointCloud对象中,所以创建一个新的PointNormal型的点云来存储坐标字段和法线连接后的点云
- pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals (new pcl::PointCloud<pcl::PointNormal>);
- pcl::concatenateFields (*cloud, *normals, *cloud_with_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);//设置连接点之间的最大距离(即为三角形最大边长)为0.025
-
- // Set typical values for the parameters设置这些参数的典型值
- gp3.setMu (2.5);//设置被样本点搜索其邻近点的最远距离为2.5,为了适应点云密度的变化。
- gp3.setMaximumNearestNeighbors (100);//设置样本点可搜索的领域点个数为100
- gp3.setMaximumSurfaceAngle(M_PI/4); // 设置某点法线方向偏离样本点法线方向的最大角度为45度
- gp3.setMinimumAngle(M_PI/18); // 设置三角化后得到的三角形最小角度为10度
- gp3.setMaximumAngle(2*M_PI/3); // 设置三角化后得到的三角形最大角度为120度
- gp3.setNormalConsistency(false);//设置该参数保证法线朝向一致
-
- // Get result 获取重建结果
- gp3.setInputCloud (cloud_with_normals);//设置输入点云为有向点云cloud_with_normals
- gp3.setSearchMethod (tree2);//设置搜索方式为tree2
- gp3.reconstruct (triangles);//重建提取三角化,开始重建
-
- // Additional vertex information 附加顶点信息
- std::vector<int> parts = gp3.getPartIDs();
- std::vector<int> states = gp3.getPointStates();
- saveVTKFile ("mesh.vtk", triangles);//保存为vtk文件
- // Finish
- return (0);
- }
修改最大距离和最远距离后,拿雷达户外实地采集的数据试了试,确实能够将点云网格化,但是点云个数太多了,耗时过长,要想实现实时重建还是难的。不过看懂例程已经成功一小步啦,下班。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。