目录
- 一、概述
- 二、代码
- 三、结果
一、概述
PCL中的 pcl::Poisson<pcl::PointXYZRGBNormal>:
函数实现泊松重建的代码示例。
二、代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/surface/poisson.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
// 可视化点云和mesh模型
void PointCloudandMeshViewer(pcl::PointCloud<pcl::PointXYZRGB>::Ptr& cloud, pcl::PolygonMesh& triangles)
{
// 输出结果到可视化窗口
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D PointCloud Viewer"));
// 设置视口1,显示原始点云
int v1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v1); // 黑色背景
viewer->addText("Original PointCloud", 10, 10, "vp1_text", v1); // 标题
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> cloud_color_handler(cloud, 0, 255, 0); // 绿色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", v1);
// 设置视口2,显示重建点云
int v2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右侧窗口
viewer->setBackgroundColor(0.0, 0.0, 1.0, v2); // 白色背景
viewer->addText("mesh", 10, 10, "vp2_text", v2);
viewer->addPolygonMesh(triangles, "triangles", v2);
viewer->setRepresentationToWireframeForAllActors(); // 网格模型以线框图模式显示
// 添加坐标系
/* viewer->addCoordinateSystem(0.1);
viewer->initCameraParameters();*/
// 可视化循环
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
}
int main()
{
// 读取点云数据
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
if (pcl::io::loadPCDFile("lamp.pcd", *cloud))
{
PCL_ERROR("Couldn't read the PCD files!\n");
return -1;
}
// 计算法线
pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> n;
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);
n.setInputCloud(cloud);
n.setSearchMethod(tree);
n.setKSearch(20); // k邻域搜索范围
pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
n.compute(*normals);
// 连接点坐标及法向量
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr cloudNormals(new pcl::PointCloud<pcl::PointXYZRGBNormal>);
pcl::concatenateFields(*cloud, *normals, *cloudNormals);
// 泊松重建
pcl::Poisson<pcl::PointXYZRGBNormal> ps;
pcl::search::KdTree<pcl::PointXYZRGBNormal>::Ptr tree1(new pcl::search::KdTree<pcl::PointXYZRGBNormal>);
tree1->setInputCloud(cloudNormals);
ps.setSearchMethod(tree1);
ps.setInputCloud(cloudNormals);
ps.setDepth(6); // 将用于表面重建的树的最大深度
ps.setMinDepth(2); // 将用于表面重建的树的最小深度
ps.setScale(1.5); // 用于重建的立方体的直径与样本的边界立方体直径的比值
ps.setSolverDivide(3); // 块高斯-塞德尔求解器用于求解拉普拉斯方程的深度。
ps.setIsoDivide(6); // 块等表面提取器用于提取等表面的深度
ps.setSamplesPerNode(10); // 每个八叉树节点上最少采样点数目
ps.setConfidence(false); // 置信标志,为true时,使用法线向量长度作为置信度信息,false则需要对法线进行归一化处理
ps.setManifold(false); // 流行标志,如果设置为true,则对多边形进行细分三角话时添加重心,设置false则不添加
ps.setOutputPolygons(false);// 是否输出为多边形(而不是三角化行进立方体的结果)。
pcl::PolygonMesh triangles; // 存储最终三角化的网格模型
ps.performReconstruction(triangles);
pcl::io::savePLYFile("lamp.ply", triangles);
// 输出可视化结果到渲染窗口
PointCloudandMeshViewer(cloud, triangles);
return (0);
}