PCL实现泊松表面重建

21 篇文章 9 订阅

简介:
泊松表面重建是一种隐函数的重构方法。通过定义模型内部的值大于零, 模型外部它的值小于零, 然后提取值为零的等值面, 直接地重构逼近表面。
泊松表面重建的算法融合了全局和局部方法的优点,采取隐性拟合的方式,通过求解泊松方程来取得点云模型所描述的表面信息代表的隐性方程,通过对该方程进行等值面提取,从而得到具有几何实体信息的表面模型。优点在于,重建出的模型具有水密性的封闭特征,具有良好的几何表面特性和细节特性。

/** Filename: Poisson_reconstruction

 ** Date: 2018-3-29

 **Description: 

**/

#include "stdafx.h"
#include <iostream>
#include <string>

#include <pcl\io\pcd_io.h>
#include <pcl\io\ply_io.h>

#include <pcl\point_types.h>

#include <pcl\kdtree\kdtree_flann.h>
#include <pcl\features\normal_3d.h>
#include <pcl\features\normal_3d_omp.h>

#include <pcl\surface\poisson.h>
#include <pcl\surface\gp3.h>

#include <pcl\visualization\cloud_viewer.h>
#include <pcl\visualization\pcl_visualizer.h>

//多线程
#include <boost\thread\thread.hpp>

#include <vector>
using namespace std;

struct Node
{
	float x;
	float y;
	float z;
	float i;
	float j;
	float k;
};

int _tmain(int argc, _TCHAR* argv[])
{
	pcl::PointCloud<pcl::PointXYZ> ::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);

	ifstream in0;
	in0.open("FanBlade.asc",ios::in);
	if(!in0.is_open())
	{
		cout<<"error open!"<<endl;
		system("pause");
		return -1;
	}
	vector<Node> points;
	points.clear();
	Node tmp;
	while(in0>>tmp.x>>tmp.y>>tmp.z>>tmp.i>>tmp.j>>tmp.k)
		points.push_back(tmp);
	pcl::PointXYZ cltmp;

	for(size_t i = 0 ;i<points.size();++i)
	{
		cltmp.x = points[i].x; 
		cltmp.y = points[i].y; 
		cltmp.z = points[i].z; 
		cloud->points.push_back(cltmp); 
	}
	//pcl::io::loadPCDFile("rabbit.pcd ",*cloud);

	cout << cloud->points.size() << endl;  

	// 计算法向量
	pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>); //法向量点云对象指针
	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中

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

	//创建搜索树
	pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>) ;
	tree2->setInputCloud(cloud_with_normals) ;
	//创建Poisson对象,并设置参数
	pcl::Poisson<pcl::PointNormal> pn ;
	pn.setConfidence(false); //是否使用法向量的大小作为置信信息。如果false,所有法向量均归一化。
	pn.setDegree(2); //设置参数degree[1,5],值越大越精细,耗时越久。
	pn.setDepth(8); //树的最大深度,求解2^d x 2^d x 2^d立方体元。由于八叉树自适应采样密度,指定值仅为最大深度。
	pn.setIsoDivide(8); //用于提取ISO等值面的算法的深度
	pn.setManifold(false); //是否添加多边形的重心,当多边形三角化时。 设置流行标志,如果设置为true,则对多边形进行细分三角话时添加重心,设置false则不添加
	pn.setOutputPolygons(false); //是否输出多边形网格(而不是三角化移动立方体的结果)
	pn.setSamplesPerNode(9); //设置落入一个八叉树结点中的样本点的最小数量。无噪声,[1.0-5.0],有噪声[15.-20.]平滑
	pn.setScale(1.25); //设置用于重构的立方体直径和样本边界立方体直径的比率。
	pn.setSolverDivide(8); //设置求解线性方程组的Gauss-Seidel迭代方法的深度

	//设置搜索方法和输入点云
	pn.setSearchMethod(tree2);
	pn.setInputCloud(cloud_with_normals);
	//创建多变形网格,用于存储结果
	pcl::PolygonMesh mesh ;
	//执行重构
	pn.performReconstruction(mesh);

	//保存网格图
	pcl::io::savePLYFile("FanBlade.ply", mesh);

	// 显示结果图
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer")) ;
	viewer->setBackgroundColor(0.5, 0.5 ,1) ;
	viewer->addPolygonMesh(mesh , "Blade") ;
	viewer->addCoordinateSystem (50.0);
	viewer->initCameraParameters();
	while (!viewer->wasStopped()){
		viewer->spinOnce(100) ;
		boost::this_thread::sleep(boost::posix_time::microseconds(100000)) ;
	}
	system("pause");
	return 0;
}


这里写图片描述

  • 4
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
三维泊松表面重建是一种常用的点云数据处理方法,可以将离散的点云数据重建成连续的三维表面模型。PCL(Point Cloud Library)是一个开源的点云处理库,提供了许多实用的算法和工具函数,包括三维泊松表面重建算法。 在PCL中使用三维泊松表面重建算法,你可以按照以下步骤进行操作: 1. 使用PCL加载点云数据:首先,你需要使用PCL库中的函数将点云数据加载到程序中。可以使用`pcl::io::loadPCDFile()`函数加载`.pcd`格式的点云文件,或者使用其他合适的函数加载其他格式的点云数据。 2. 对点云进行预处理:在进行泊松表面重建之前,有时需要对点云进行预处理,例如去除离群点、滤波等。PCL提供了许多预处理的方法,可以根据具体情况选择合适的方法进行处理。 3. 执行三维泊松表面重建:使用`pcl::Poisson`类可以进行三维泊松表面重建。你需要创建一个`pcl::Poisson`对象,并将预处理后的点云数据传递给它。然后,调用`performReconstruction()`函数执行重建过程。 4. 获取重建的三维模型:重建完成后,你可以使用`pcl::PolygonMesh`对象来获取重建的三维模型。可以使用`pcl::toPCLPointCloud2()`函数将重建的模型转换为点云格式,或者直接保存为`.ply`等格式的文件。 需要注意的是,三维泊松表面重建是一个计算密集型的算法,对于大规模的点云数据可能需要较长的运行时间。此外,泊松表面重建的结果可能受到输入点云的质量和密度等因素的影响,需要根据具体情况进行调整和优化。 希望以上信息对你有帮助!如果你还有其他问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值