基于PCL的三维重建—贪婪投影三角化算法实践与参数设置

来源:互联网 发布:淘宝网短袖圆领男内衣 编辑:程序博客网 时间:2024/05/20 20:05

贪婪投影三角化算法

主要方法:先将有向点云投影到某一局部二维坐标平面内,再在坐标平面内进行平面内的三角化,再根据平面内三位点的拓扑连接关系获得一个三角网格曲面模型。

主要原理:处理一系列可以使网格“生长扩大”的点(边缘点),延伸这些点直到所有符合几何正确性和拓扑正确性的点都被连上。该算法的优点是可以处理来自一个或者多个扫描仪扫描得到并且有多个连接处的散乱点云。但该算法也有一定的局限性,它更适用于采样点云来自于表面连续光滑的曲面并且点云密度变化比较均匀的情况。

主要代码:

pcl::PolygonMesh triangles;//创建多变形网格,用于存储结果//设置GreedyProjectionTriangulation对象的参数//第一个参数影响很大gp3.setSearchRadius(15.0f); //设置连接点之间的最大距离(最大边长)用于确定k近邻的球半径【默认值 0】gp3.setMu(5.0f); //设置最近邻距离的乘子,以得到每个点的最终搜索半径【默认值 0】gp3.setMaximumNearestNeighbors(100); //设置搜索的最近邻点的最大数量gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees(pi)最大平面角gp3.setMinimumAngle(M_PI / 18); // 10 degrees 每个三角的最小角度gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees 每个三角的最大角度gp3.setNormalConsistency(false); //如果法向量一致,设置为true//设置搜索方法和输入点云gp3.setInputCloud(cloud_with_normals);gp3.setSearchMethod(tree2);//执行重构,结果保存在triangles中gp3.reconstruct(triangles);

完整代码:

#include <pcl/point_types.h>#include <pcl/io/pcd_io.h>#include <pcl/io/ply_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>#include <boost/thread/thread.hpp>#include <fstream>#include <iostream>#include <stdio.h>#include <string.h>#include <string>typedef pcl::PointXYZ PointT;typedef pcl::PointCloud<PointT> PointCloudT;int main(int argc, char** argv){//打开文件PointCloudT::Ptr cloud(new PointCloudT);if (pcl::io::loadPCDFile<pcl::PointXYZ>("face2.pcd", *cloud) == -1){PCL_ERROR("Couldn't read file1 \n");return (-1);}// 估计法向量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中//* normals 不能同时包含点的法向量和表面的曲率//将点云和法线放到一起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//创建搜索树pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);tree2->setInputCloud(cloud_with_normals);//初始化GreedyProjectionTriangulation对象,并设置参数pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;//创建多变形网格,用于存储结果pcl::PolygonMesh triangles;//设置GreedyProjectionTriangulation对象的参数//第一个参数影响很大gp3.setSearchRadius(15.0f); //设置连接点之间的最大距离(最大边长)用于确定k近邻的球半径【默认值 0】gp3.setMu(5.0f); //设置最近邻距离的乘子,以得到每个点的最终搜索半径【默认值 0】gp3.setMaximumNearestNeighbors(100); //设置搜索的最近邻点的最大数量gp3.setMaximumSurfaceAngle(M_PI / 4); // 45 degrees(pi)最大平面角gp3.setMinimumAngle(M_PI / 18); // 10 degrees 每个三角的最小角度gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees 每个三角的最大角度gp3.setNormalConsistency(false); //如果法向量一致,设置为true//设置搜索方法和输入点云gp3.setInputCloud(cloud_with_normals);gp3.setSearchMethod(tree2);//执行重构,结果保存在triangles中gp3.reconstruct(triangles);//保存网格图pcl::io::savePLYFile("result.ply", 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, "my"); //设置显示的网格viewer->addCoordinateSystem(1.0); //设置坐标系viewer->initCameraParameters();while (!viewer->wasStopped()){viewer->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return (0);}


常见错误:PCLVisualizer::addPolygonMesh: No polygons

解决方法:不同的pcd文件,主要需要重设setSearchRadius与setMu



阅读全文
0 0
原创粉丝点击