【PCL-3】点云模型网格化--贪婪投影三角化算法

贪婪投影三角化算法是一种对原始点云进行快速三角化的算法,该算法假设曲面光滑,点云密度变化均匀,不能在三角化的同时对曲面进行平滑和孔洞修复。

方法:

(1)将三维点通过法线投影到某一平面;

(2)对投影得到的点云作平面内的三角化;

(3)根据平面内三位点的拓扑连接关系获得一个三角网格曲面模型。

在平面区域的三角化过程中用到了基于Delaunay的空间区域增长算法,该方法通过选取一个样本三角片作为初始曲面,不断扩张曲面边界,最后形成一张完整的三角网格曲面,最后根据投影点云的连接关系确定各原始三维点间的拓扑连接,所得的三角网格即为重建得到的曲面模型。

该算法适用于采样点云来自表面光滑连续的曲面,且点云密度变化比较均匀的情况。

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


int main()
{
	// 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("E://TY//camport3-master//cylinder.pcd", cloud_blob);
	pcl::fromPCLPointCloud2(cloud_blob, *cloud); //* the data should be available in cloud //
	//法线估计对象
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n;

	//存储估计的法线
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	//定义kd树指针
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZ>);
	tree1->setInputCloud(cloud);
	n.setInputCloud(cloud);
	n.setSearchMethod(tree1);
	n.setKSearch(30);
	//估计法线存储到其中
	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; // 设置连接点之间的最大距离,即是三角形最大边长
	gp3.setSearchRadius(20.625);
	//设置各种参数
	gp3.setMu(2.5); //设置被样本点搜索其邻近点的最远距离,使点云密度的变化
	gp3.setMaximumNearestNeighbors(100);  // 设置样本可搜索的领域个数
	gp3.setMaximumSurfaceAngle(M_PI / 4); // 设置某点法线方向偏离样本点法线的最大角度45
	gp3.setMinimumAngle(M_PI / 18); // 设置三角化后得到的三角形内角的最小的角度为10
	gp3.setMaximumAngle(2 * M_PI / 3); // 设置三角化后得到的三角形内角的最大角度为120
	gp3.setNormalConsistency(false); // 设置该参数保证法线朝向一致
	//设置搜索方法和输入点云
	gp3.setInputCloud(cloud_with_normals);
	gp3.setSearchMethod(tree2);
	//执行重构,结果保存在triangles中
	gp3.reconstruct(triangles); // Additional vertex information

	//保存网格图
	std::string output_dir = "E://TY//camport3-master//cloud_mesh.ply";
	std::string sav = "saved mesh in:";
	sav += output_dir;
	pcl::console::print_info(sav.c_str());
	std::cout << std::endl;

	pcl::io::savePLYFileBinary(output_dir.c_str(), triangles);
	//可视化
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	viewer->addPolygonMesh(triangles, "triangles");
	viewer->addPolylineFromPolygonMesh(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);
}

注:调整setSearchRadius(20.625)参数。

测试

原始点云

 1、参数

gp3.setSearchRadius(35.8);
​​​​​​​gp3.setMu(2.5);
gp3.setMaximumNearestNeighbors(2000);

结果:

2、参数

gp3.setSearchRadius(5);
gp3.setMu(500);
gp3.setMaximumNearestNeighbors(2000);

结果:

3、参数

gp3.setSearchRadius(35.8);
gp3.setMu(500);
gp3.setMaximumNearestNeighbors(2000);

结果:

 

参考链接 https://www.cnblogs.com/baby123/p/10956399.html

pcl几种表面重建_pcl表面重建_3D_DLW的博客-CSDN博客

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值