pcl 三维重建 vtk Delaunay 点云网格化

8 篇文章 1 订阅

 点云三维重建主要有:

delaunay

- MC

- Poisson

- Stich

- Level set

网格主要用于计算机图形学中,有三角、四角网格等很多种。
计算机图形学中的网格处理绝大部分都是基于三角网格的,三角网格在图形学和三维建模中使用的非常广泛,用来模拟复杂物体的表面,如建筑、车辆、动物等,你看下图中的兔子、球等模型都是基于三角网格的

三角形表示网格也叫三角剖分。它有如下几个优点:

    三角网格稳定性强。

    三角网格比较简单(主要原因),实际上三角网格是最简单的网格类型之一,可以非常方便并且快速生成,在非结构化网格中最常见。而且相对于一般多边形网格,许多操作对三角网格更容易。
 

目前点云进行网格生成一般分为两大类方法:

  • 插值法。顾名思义,也就是重建的曲面都是通过原始的数据点得到的

  • 逼近法。用分片线性曲面或其他曲面来逼近原始数据点,得到的重建曲面是原始点集的一个逼近。

点云贪心三角化

#include <iostream>

#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
 
#include<vtkRenderWindow.h>
#include<vtkSmartPointer.h>

#include <vtkSmartPointer.h>
#include <vtkPolyDataReader.h>
#include <vtkPolyData.h>
#include <vtkSurfaceReconstructionFilter.h>
#include <vtkContourFilter.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkCamera.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkPolyDataNormals.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
 

#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkNamedColors.h>
#include <vtkProperty.h>
#include <vtkSmartPointer.h>

#include <vtkRenderWindow.h>
#include <vtkPlanes.h>

#include <vtkProperty.h>

#include <vtkSmartPointer.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkCubeSource.h>

#include <vtkAlgorithmOutput.h>
#include <vtkCleanPolyData.h>
#include <vtkTriangleFilter.h>


#include <vtkStripper.h>
#include <vtkSTLWriter.h>

#include <vtkNew.h>
using namespace std;

//#define FILE_PATH "xiaomianpian.XYZN"
//#define FILE_PATH "2DpointDatas.txt"

#include <vtkStripper.h>
#include <vtkSTLWriter.h>
#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/io/vtk_lib_io.h>
#include <vtkNew.h>
#include <pcl/io/vtk_io.h>
using namespace std;

#define FILE_PATH "sxiaomianpian.XYZN"

/ 

---------------读取txt文件-------------------
void CreateCloudFromTxt(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud, pcl::PointCloud<pcl::Normal>::Ptr normals)
{
	std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
	std::string line;
	pcl::PointXYZ point;
	pcl::Normal nPoint;

	int index = 0;
	while (getline(file, line)) {
		std::stringstream ss(line);
		ss >> point.x;
		ss >> point.y;
		ss >> point.z;

		ss >> nPoint.normal_x;
		ss >> nPoint.normal_y;
		ss >> nPoint.normal_z;

		cloud->push_back(point);
		normals->push_back(nPoint);
		//printf("%f,%f,%f\n", point.x, point.y, point.z);

	}
	file.close();
	printf("size %ld\n", cloud->size());
}
int main(int argc, char** argv)
{
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	//pcl::io::loadPCDFile(FILE_PATH, *cloud);
	 pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);   //存储估计的法线
	CreateCloudFromTxt(FILE_PATH, cloud, normals);
	//CreateCloudFromTxt(FILE_PATH, cloud);
//	printf("size %d\n", cloud->size());
	//pcl::visualization::PCLVisualizer   viewer("viewer");
	//viewer.addPointCloud(cloud);
	//viewer.spin();

	 // 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>);  //定义kd树指针
	//tree->setInputCloud(cloud);   ///用cloud构建tree对象
	//n.setInputCloud(cloud);
	//n.setSearchMethod(tree);
	//n.setKSearch(20);
	//n.compute(*normals);       估计法线存储到其中
	//* normals should not contain the point normals + surface curvatures
	printf("normals=========\n");
	// 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
	printf("111normals=========\n");
	//定义搜索树对象
	pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
	tree2->setInputCloud(cloud_with_normals);   //点云构建搜索树
	printf("22 normals=========\n");
	// Initialize objects
	pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;   //定义三角化对象
	pcl::PolygonMesh triangles;                //存储最终三角化的网络模型

 

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

	std::cout << "Triangling..." << std::endl;
	gp3.setSearchRadius(10);//设置连接点之间的最大距离(即为三角形最大边长)为0.025
	std::cout << "1" << std::endl;
	gp3.setMu(1);//设置被样本点搜索其邻近点的最远距离为2.5,为了适应点云密度的变化
	std::cout << "2" << std::endl;
	gp3.setMaximumNearestNeighbors(100);//设置样本点可搜索的邻域个数
	std::cout << "3" << std::endl;
	gp3.setMaximumSurfaceAngle(M_PI / 12);//45,180/4,设置某点法线方向偏离样本点法线方向的最大角度为45度
	std::cout << "4" << std::endl;
	gp3.setMinimumAngle(M_PI / 18);//10,180/18,设置三角化后得到三角形内角最小角度为10度
	std::cout << "5" << std::endl;
	gp3.setMaximumAngle(2 * M_PI / 12);//120,2*180/3,设置三角化后得到三角形内角最大角度为120度
	std::cout << "6" << std::endl;
	gp3.setNormalConsistency(true); //设置该参数保证法线朝向一致
	std::cout << "7" << std::endl;

	gp3.setInputCloud(cloud_with_normals);
	std::cout << "8" << std::endl;
	gp3.setSearchMethod(tree2);//设置搜索方式tree2
	std::cout << "Triangling..." << std::endl;
	gp3.reconstruct(triangles);//重建提取三角化
	std::cout << "Finshed..." << std::endl;
	pcl::io::saveVTKFile("wenwu_result.vtk", triangles);
	//std::cout << "Done..." << std::endl;
	std::cout << "Saved..." << std::endl;

	pcl::io::savePolygonFile("wenwu_result.stl", triangles);
	//std::vector<int> parts = gp3.getPartIDs();//附加定点信息
	//std::vector<int> states = gp3.getPointStates();

	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("可视化"));//三维可视化窗口
	viewer->setBackgroundColor(0, 0, 0);
	viewer->addPolygonMesh(triangles, "my");
	viewer->addCoordinateSystem(50.0);
	viewer->initCameraParameters();

	while (!viewer->wasStopped()) {
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
	std::cout << "Done..." << std::endl;

	//pcl::io::saveVTKFile("mianpian.vtk", triangles);

	//pcl::io::loadPolygonFile(const std::string &file_name, pcl::PolygonMesh& mesh);
	printf("saveVTKFile=========\n");
	system("pause");
	return 0;
}

Delaunay

void saveSTL(vtkPolyData* StlPolyData)
{
	vtkNew<vtkSTLWriter> stlWriter;
	stlWriter->SetFileName("./db-out.stl");
	stlWriter->SetInputData((vtkDataObject *)StlPolyData );
	stlWriter->Update();
	stlWriter->Write();
}
int main()
{
	
	//vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New();	//_存放细胞顶点,用于渲染(显示点云所必须的)
	vtkSmartPointer<vtkPolyData> polyData = vtkSmartPointer<vtkPolyData>::New();
	//vtkSmartPointer<vtkPolyDataMapper> pointMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	//vtkSmartPointer<vtkActor> pointActor = vtkSmartPointer<vtkActor>::New();
	//vtkSmartPointer<vtkRenderer> ren1 = vtkSmartPointer< vtkRenderer>::New();
	//vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
	//vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	//vtkSmartPointer<vtkInteractorStyleTrackballCamera> istyle = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();

	vtkSmartPointer<vtkPoints> m_Points = vtkSmartPointer<vtkPoints>::New();

	//_读进点云数据信息

	ifstream infile(FILE_PATH, ios::in);
	double x, y, z;
	char line[128];
	int i = 0;
	while (infile.getline(line, sizeof(line)))
	{
		stringstream ss(line);
		ss >> x;
		ss >> y;
		ss >> z;

		m_Points->InsertPoint(i, x, y, z);		//_加入点信息
		///vertices->InsertNextCell(1);		//_加入细胞顶点信息----用于渲染点集
		//vertices->InsertCellPoint(i);
		i++;
	}
	infile.close();

	//_创建待显示数据源

	polyData->SetPoints(m_Points);		//_设置点集

	// Triangulate the grid points
	vtkSmartPointer<vtkDelaunay2D> delaunay =
		vtkSmartPointer<vtkDelaunay2D>::New();
	delaunay->SetInputData(polyData);
	delaunay->SetAlpha(10);
	//delaunay->SetTolerance(0.1);
	delaunay->Update();

	saveSTL(delaunay->GetOutput());
	// Visualize
	vtkSmartPointer<vtkNamedColors> colors =
		vtkSmartPointer<vtkNamedColors>::New();

	vtkSmartPointer<vtkPolyDataMapper> meshMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	meshMapper->SetInputConnection(delaunay->GetOutputPort());

	vtkSmartPointer<vtkActor> meshActor =
		vtkSmartPointer<vtkActor>::New();
	meshActor->SetMapper(meshMapper);
	//meshActor->GetProperty()->SetColor(colors->GetColor3d("Banana").GetData());
	meshActor->GetProperty()->EdgeVisibilityOn();

	vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =
		vtkSmartPointer<vtkVertexGlyphFilter>::New();
	glyphFilter->SetInputData(polyData);

	vtkSmartPointer<vtkPolyDataMapper> pointMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	pointMapper->SetInputConnection(glyphFilter->GetOutputPort());

	vtkSmartPointer<vtkActor> pointActor =
		vtkSmartPointer<vtkActor>::New();
	//pointActor->GetProperty()->SetColor(colors->GetColor3d("Tomato").GetData());
	pointActor->GetProperty()->SetPointSize(5);
	pointActor->SetMapper(pointMapper);

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderer->AddActor(meshActor);
	renderer->AddActor(pointActor);
	//renderer->SetBackground(colors->GetColor3d("Mint").GetData());

	renderWindow->Render();
	renderWindowInteractor->Start();
}

显示点云,非三角化

 pcl::PointCloud<pcl::PointXYZ>  cloud;
	vtkSmartPointer<vtkPoints>points = vtkSmartPointer<vtkPoints>::New();//点数据
	vtkSmartPointer<vtkCellArray> vertices = vtkSmartPointer<vtkCellArray>::New(); 

	int count = cloud.points.size();
	std::cout << "old point s count : " << count << "  " << std::endl;
	for (int i = 0; i < count; i++)
	{
		//定义存储顶点索引的中间变量,类似Int、long类型
		vtkIdType pointId[1];
		//将每个点的坐标加入vtkPoints,InsertNextPoint()返回加入点的索引号
		pointId[0] = points->InsertNextPoint(cloud.points[i].x, cloud.points[i].y, cloud.points[i].z);
		//为每个坐标点分别创建一个顶点,顶点是单元类型里面的一种
		vertices->InsertNextCell(1, pointId);
	}

	//指定数据的几何结构(由points指定)和拓扑结构(由vertices指定)
	polyData->SetPoints(points);
	polyData->SetVerts(vertices);

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: Python-PCL是一个Python绑定库,它提供了对PointCloud库的访问。点云网格化算法是将点云数据进行处理后生成一张网格表面的算法。网格化可以使点云数据更容易可视化、分析和处理。Python-PCL点云网格化算法可以将点云数据分割成均匀分布的三角形网格,并构建一个平滑的网格表面。 Python-PCL点云网格化算法的主要步骤包括: 1.加载点云数据并将其转换为PointNormal格式,以便于法线估计和网格化操作。 2.对点云数据进行法线估计。该过程使用一种求点云曲率的技术,将每个点的法线计算出来,并保存在其对应的点中。 3.将法线信息与点云数据结合,构建一个SurfaceReconstruction3D对象来执行网格化操作。在这个过程中,算法使用一个梯度下降优化算法,将点云数据映射到一个均匀分布的三角形网格上。优化约束条件限制每个三角形的边长,使网格表面更加平滑。 4.最后根据三角形间的相交情况对网格进行修复,并输出网格数据。在这个过程中,算法检查每个三角形是否与其他三角形相交,并尝试通过联通、压缩网格等修复操作,使网格曲面更加平滑。 Python-PCL点云网格化算法是一种实现点云数据可视化、处理和分析的有效工具。在3D打印、机器人视觉和虚拟现实等领域都有广泛的应用。 ### 回答2: Python-PCL是一个Python的PCL(点云库)封装库,允许用户在Python中使用PCL中的众多算法。点云网格化算法就是Python-PCL之中的一个非常重要的算法。 点云网格化算法是将点云数据转化为网格表示的过程,在这个过程中,将点云数据转换为一个等间距的二元矩阵表示。由于点云数据是一个由众多点组成的体,因此,这个矩阵是被空缺的网格填充而成的。在这个过程中,点云数据通过多次计算,不断地从自由形状变为一种规则形状,从而提高点云数据的处理效率。 点云网格化算法是通过点云曲面重构的算法实现的。曲面重构算法能够将点云数据转化为一个规则的几何模型,从而为相关应用提供了非常大的便捷,因此,点云网格化算法的应用非常广泛,例如:机器视觉,三维打印等方面。在Python-PCL的应用中,点云网格化算法的实现基于VTK(Visualization ToolKit)工具包,通过VTK包中的vtkPolyDataMapper类实现点云网格化点云网格化算法的实现需要通过多次迭代计算,使点云数据沿着均匀分布的空间方向发生变化,从而最终能够得到一种规则的几何形状。在实际应用中,点云数据可能会受到很多干扰,例如:噪音、数据不完整等因素,这对点云网格化算法的计算效率提出了非常高的要求,因此,Python-PCL提供了一系列优化的算法来满足实际应用的需求。 ### 回答3: Python-PCL是Point Cloud Library的Python封装库,提供了一组Python模块,可以在Python中使用PCL的功能。PCL是一个C++库,是开发点云处理算法和应用的一流工具,具有许多点云处理功能,如配准、滤波、分割、聚类、特征提取和识别等。 点云网格化是一种将点云转化为网格模型的技术。在点云数据中,所有的点都是离散的,而在网格模型中,点是有序的,因此点云网格化是将离散的点云数据转换为有序的网格数据的过程。 Python-PCL库提供了函数pcl.surface包来执行点云到三角网格转换,使用点云同步方法定义的半径搜索方式构建三角网格。 下面是一个简单的例程,它将点云转换为三角网格: ```python import pcl cloud = pcl.PointCloud.PointXYZRGB() mesh = cloud.make_mesh_cuboid() print('PointCloud before meshing') print(cloud) print('PointCloud after meshing') print(mesh.cloud) print(mesh.polygons) ``` 该例程首先定义了一个PointCloud对象,然后使用make_mesh_cuboid()函数将其转换为三角网格。最后,程序将输出PointCloud以及转换后的mesh。由于make_mesh_cuboid()函数是在一个立方体形状上生成网格对象,因此输出结果可能会有所不同。 总体而言,Python-PCL是一个非常强大的工具,它为Python程序员提供了使用点云数据处理的功能。尤其是对于点云网格化算法,Python-PCL提供了一个方便的方式来将点云数据转换为有序的网格数据。这个库是在点云领域做开发非常有帮助的,它为点云的开发和应用提供了大量的可靠和高效的处理工具。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

恋恋西风

up up up

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值