pcl曲面重建模塊-貪婪三角形投影算法實例


貪婪三角形投影算法
在pcl-1.8測試

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/vtk_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/thread/thread.hpp>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string.h>

int main(int argc, char** argv)
{
	// 點雲模型讀入,此處讀入為PCD格式點雲文件.數據類型為PointXYZ.
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	if (pcl::io::loadPCDFile<pcl::PointXYZ>(argv[1], *cloud) == -1)
	{
		PCL_ERROR("Couldn't read file mypointcloud.pcd\n");  //若讀取失敗將提示
		return -1;
	}
	std::cerr << "點雲讀入   完成" << std::endl;
	//sensor_msgs::PointCloud2 cloud_blob;
	//pcl::io::loadPCDFile ("bun0.pcd", cloud_blob);
	//pcl::fromROSMsg (cloud_blob, *cloud);
	//* the data should be available in 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>);//創建kdtree用於法向計算時近鄰搜索
	tree->setInputCloud(cloud);//為kdtree輸入點雲
	n.setInputCloud(cloud);//為法向估計對象輸入點雲
	n.setSearchMethod(tree);//設置法向估計時采用的搜索方式為kdtree
	n.setKSearch(20);//設置法向估計時,k近鄰搜索的點數
	n.compute(*normals);  //進行法向估計
	
	std::cerr << "法線計算   完成" << std::endl;

	// 創建同時包含點和法向的數據結構的指針
	pcl::PointCloud<pcl::PointNormal>::Ptr cloud_with_normals(new pcl::PointCloud<pcl::PointNormal>);
	//將已獲得的點數據和法向數據拼接
	pcl::concatenateFields(*cloud, *normals, *cloud_with_normals);


	// 創建另一個kdtree用於重建
	pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>);
	//為kdtree輸入點雲數據,該點雲數據類型為點和法向
	tree2->setInputCloud(cloud_with_normals);

	// 創建貪婪三角形投影重建對象
	pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;
	//創建多邊形網格對象,用來存儲重建結果
	pcl::PolygonMesh triangles; 

	//設置參數
	gp3.setSearchRadius(25);  // 設置連接點之間的最大距離(最大邊長)用於確定k近鄰的球半徑(默認為0)
	gp3.setMu(2.5);  // 設置最近鄰距離的乘子,已得到每個點的最終搜索半徑(默認為0)
	gp3.setMaximumNearestNeighbors(100);  //設置搜索的最近鄰點的最大數量
	gp3.setMaximumSurfaceAngle(M_PI / 2); // 45 degrees 最大平面角
	gp3.setMinimumAngle(M_PI / 18); // 10 degrees 每個三角的最大角度
	gp3.setMaximumAngle(2 * M_PI / 3); // 120 degrees
	gp3.setNormalConsistency(false);  //若法向量一致,設為true

	// 設置點雲數據和搜索方式
	gp3.setInputCloud(cloud_with_normals);
	gp3.setSearchMethod(tree2);

	//開始重建
	gp3.reconstruct(triangles);

	std::cerr << "重建   完成" << std::endl;

	//將重建結果保存到硬盤文件中,重建結果以VTK格式存儲
	pcl::io::saveVTKFile("mymesh.vtk", triangles); 

	// Additional vertex information
	std::vector<int> parts = gp3.getPartIDs();
	std::vector<int> states = gp3.getPointStates();
	fstream fs;
	fs.open("partsID.txt", ios::out);
	if (!fs)
	{
		return -2;
	}
	fs << "點雲數量為:" << parts.size() << "\n";
	for (int i = 0; i < parts.size(); i++)
	{
		if (parts[i] != 0)
		{
			fs << parts[i] << "\n";   //這的fs對嗎?
		}
	}

	std::cerr << "開始顯示 ........" << std::endl;

	//圖形顯示模塊
	//創建顯示對象指針
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0.6);  //設置窗口顏色
	viewer->addPolygonMesh(triangles, "my");  //設置所要顯示的網格對象
	viewer->addCoordinateSystem(0.1);  //設置坐標系,參數為坐標顯示尺寸
	viewer->initCameraParameters();
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}


	// Finish
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM