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

贪婪投影三角化算法

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

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

主要代码:

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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud PointCloudT;
int main(int argc, char** argv)
{
	//打开文件
	PointCloudT::Ptr cloud(new PointCloudT);
	if (pcl::io::loadPCDFile("face2.pcd", *cloud) == -1)
	{
		PCL_ERROR("Couldn't read file1 \n");
		return (-1);
	}
	// 估计法向量
	pcl::NormalEstimation n;
	pcl::PointCloud::Ptr normals(new pcl::PointCloud);
	pcl::search::KdTree::Ptr tree(new pcl::search::KdTree);
	tree->setInputCloud(cloud);
	n.setInputCloud(cloud);
	n.setSearchMethod(tree);
	n.setKSearch(20);
	n.compute(*normals); //计算法线,结果存储在normals中
	//* normals 不能同时包含点的法向量和表面的曲率

	//将点云和法线放到一起
	pcl::PointCloud::Ptr cloud_with_normals(new pcl::PointCloud);
	pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);
	//* cloud_with_normals = cloud + normals

	//创建搜索树
	pcl::search::KdTree::Ptr tree2(new pcl::search::KdTree);
	tree2->setInputCloud(cloud_with_normals);

	//初始化GreedyProjectionTriangulation对象,并设置参数
	pcl::GreedyProjectionTriangulation 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 parts = gp3.getPartIDs();
	//std::vector states = gp3.getPointStates();

	// 显示结果图
	boost::shared_ptr 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

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


你可能感兴趣的:(三维重建)