PCL学习笔记——点云数据通过贪婪三角投影算法生成三角网格

时间:2024-04-08 13:27:40
PointCloud和PCLPointCloud2区别:

一、PointCloud:

Public Attributes:

pcl::PCLHeader header( The point cloud header. )
std::vector< PointT, Eigen::aligned_allocator< PointT > >points( The point data. )
uint32_t width (The point cloud width (if organized as an image-structure).)
uint32_t height (The point cloud height (if organized as an image-structure). )
bool is_dense (True if no points are invalid (e.g., have NaN or Inf values in any of their floating point fields). )
Eigen::Vector4f sensor_origin_(Sensor acquisition pose (origin/translation). )
Eigen::Quaternionf sensor_orientation_(Sensor acquisition pose (rotation). )

二、PCLPointCloud2:

Public Attributes:

::pcl::PCLHeader header
pcl::uint32_t height
pcl::uint32_t width
std::vector< ::pcl::PCLPointField > fields
pcl::uint8_t is_bigendian
pcl::uint32_t point_step
pcl::uint32_t row_step
std::vector< pcl::uint8_t > data
pcl::uint8_t is_dense

三、PCLPointCloud2转换为PointCloud:

主要函数:

void pcl::fromPCLPointCloud2 ( const pcl::PCLPointCloud2 & msg,pcl::PointCloud< PointT > & cloud, const MsgFieldMap &field_map )

Parameters:

[in] msg the PCLPointCloud2 binary blob
[out] cloud the resultant pcl::PointCloud
[in] field_map a MsgFieldMap object
Convert a PCLPointCloud2 binary data blob into a pcl::PointCloud object using a field_map.

四、GreedyProjectionTriangulation()

head file:

#include<pcl/surface/gp3.h>

Constructor:

pcl::GreedyProjectionTriangulation< PointInT > Class Template Reference

GreedyProjectionTriangulation is an implementation of a greedy triangulation algorithm for 3D points based on local 2D projections.(贪婪投影算法)

code:

// triangulation_test.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<iostream>
#include<pcl/point_types.h>
#include<pcl/io/pcd_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/math/special_functions/round.hpp>

using namespace std;
int main()
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PCLPointCloud2 cloud_blob;
	pcl::io::loadPCDFile("cloud11.pcd", cloud_blob);
	pcl::fromPCLPointCloud2(cloud_blob, *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>);
	tree->setInputCloud(cloud);
	n.setInputCloud(cloud);
	n.setSearchMethod(tree);
	n.setKSearch(20);
	n.compute(*normals);  //估计法线存储位置

	//Concatenate the XYZ and normal field
	pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
	pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);  //连接字段
	//point_with_normals = cloud + normals

	//定义搜索树对象
	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(0.75);  //设置连接点之间的最大距离(即为三角形的最大边长)

	//设置各参数值
	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); //设置该参数保证法线朝向一致

	//Get Result
	gp3.setInputCloud(cloud_with_normals);  //设置输入点云为有向点云
	gp3.setSearchMethod(tree2); //设置搜索方式
	gp3.reconstruct(triangles); //重建提取三角化

	//附加顶点信息
	vector<int>parts = gp3.getPartIDs();
	vector<int>states = gp3.getPointStates();

	//Viewer
	pcl::visualization::PCLVisualizer viewer("viewer");
	viewer.addPolygonMesh(triangles);
	viewer.spin();
	
    return 0;
}

result:

PCL学习笔记——点云数据通过贪婪三角投影算法生成三角网格