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

 点云三维重建主要有:

delaunay

- MC

- Poisson

- Stich

- Level set

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

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

    三角网格稳定性强。

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

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

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

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

点云贪心三角化

#include 

#include 
#include 
 
#include
#include

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
 

#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 


#include 
#include 

#include 
using namespace std;

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

#include 
#include 
#include 
#include 
#include 
#include 
#include    
#include
#include 
#include 
using namespace std;

#define FILE_PATH "sxiaomianpian.XYZN"

/ 

---------------读取txt文件-------------------
void CreateCloudFromTxt(const std::string& file_path, pcl::PointCloud::Ptr cloud, pcl::PointCloud::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::Ptr cloud(new pcl::PointCloud);
	//pcl::PointCloud::Ptr cloud(new pcl::PointCloud);
	//pcl::io::loadPCDFile(FILE_PATH, *cloud);
	 pcl::PointCloud::Ptr normals(new pcl::PointCloud);   //存储估计的法线
	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 n;      //法线估计对象
	//pcl::PointCloud::Ptr normals(new pcl::PointCloud);   //存储估计的法线
	//pcl::search::KdTree::Ptr tree(new pcl::search::KdTree);  //定义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::Ptr cloud_with_normals(new pcl::PointCloud);
	pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);    //连接字段
	//* cloud_with_normals = cloud + normals
	printf("111normals=========\n");
	//定义搜索树对象
	pcl::search::KdTree::Ptr tree2(new pcl::search::KdTree);
	tree2->setInputCloud(cloud_with_normals);   //点云构建搜索树
	printf("22 normals=========\n");
	// Initialize objects
	pcl::GreedyProjectionTriangulation gp3;   //定义三角化对象
	pcl::PolygonMesh triangles;                //存储最终三角化的网络模型

 

	 附加顶点信息
	//std::vector parts = gp3.getPartIDs();
	//std::vector 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 parts = gp3.getPartIDs();//附加定点信息
	//std::vector states = gp3.getPointStates();

	boost::shared_ptr 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 stlWriter;
	stlWriter->SetFileName("./db-out.stl");
	stlWriter->SetInputData((vtkDataObject *)StlPolyData );
	stlWriter->Update();
	stlWriter->Write();
}
int main()
{
	
	//vtkSmartPointer vertices = vtkSmartPointer::New();	//_存放细胞顶点,用于渲染(显示点云所必须的)
	vtkSmartPointer polyData = vtkSmartPointer::New();
	//vtkSmartPointer pointMapper = vtkSmartPointer::New();
	//vtkSmartPointer pointActor = vtkSmartPointer::New();
	//vtkSmartPointer ren1 = vtkSmartPointer< vtkRenderer>::New();
	//vtkSmartPointer renWin = vtkSmartPointer::New();
	//vtkSmartPointer iren = vtkSmartPointer::New();
	//vtkSmartPointer istyle = vtkSmartPointer::New();

	vtkSmartPointer m_Points = vtkSmartPointer::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 delaunay =
		vtkSmartPointer::New();
	delaunay->SetInputData(polyData);
	delaunay->SetAlpha(10);
	//delaunay->SetTolerance(0.1);
	delaunay->Update();

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

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

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

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

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

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

	vtkSmartPointer renderer =
		vtkSmartPointer::New();
	vtkSmartPointer renderWindow =
		vtkSmartPointer::New();
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer renderWindowInteractor =
		vtkSmartPointer::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

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

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

显示点云,非三角化

 pcl::PointCloud  cloud;
	vtkSmartPointerpoints = vtkSmartPointer::New();//点数据
	vtkSmartPointer vertices = vtkSmartPointer::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);

你可能感兴趣的:(VTK,PCL,PCL,mesh)