貪婪投影三角化算法是一種對原始點雲進行快速三角化的算法,該算法假設曲面光滑,點雲密度變化均勻,不能在三角化的同時對曲面進行平滑和孔洞修復。ios
方法:算法
(1)將三維點經過法線投影到某一平面網絡
(2)對投影獲得的點雲做平面內的三角化spa
(3)根據平面內三位點的拓撲鏈接關係得到一個三角網格曲面模型3d
在平面區域的三角化過程當中用到了基於Delaunay的空間區域增加算法,該方法經過選取一個樣本三角片做爲初始曲面,不斷擴張曲面邊界,最後造成一張完整的三角網格曲面,最後根據投影點雲的鏈接關係肯定各原始三維點間的拓撲鏈接,所得的三角網格即爲重建獲得的曲面模型。指針
該算法適用於採樣點雲來自表面連續光滑的曲面且點雲的密度變化比較均勻的狀況rest
pcl1.8.1+vs2015code
#include<iostream> #include<pcl/io/pcd_io.h> #include <pcl/io/ply_io.h> #include<pcl/point_types.h> #include <pcl/kdtree/kdtree_flann.h> #include <pcl/features/normal_3d.h> #include <pcl/io/obj_io.h> #include <pcl/surface/gp3.h> #include <pcl/visualization/pcl_visualizer.h> int main(int argc, char** argv) { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>()); pcl::PCLPointCloud2 cloud_blob; //*打開點雲文件 if (pcl::io::loadPCDFile("rabbit.pcd", cloud_blob) == -1) { PCL_ERROR("Couldn't read file rabbit.pcd\n"); return(-1); } pcl::fromPCLPointCloud2(cloud_blob, *cloud); //法線估計對象 pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> n; //存儲估計的法線 pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>); //定義kd樹指針 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 fields* pcl::PointCloud<pcl::PointNormal>::Ptr cloud_width_normals(new pcl::PointCloud<pcl::PointNormal>); //連接字段 pcl::concatenateFields(*cloud, *normals, *cloud_width_normals); //定義搜索樹對象 pcl::search::KdTree<pcl::PointNormal>::Ptr tree2(new pcl::search::KdTree<pcl::PointNormal>); //點雲構建搜索樹 tree2->setInputCloud(cloud_width_normals); //定義三角化對象 pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3; //存儲最終三角化的網絡模型 pcl::PolygonMesh triangles;//設置鏈接點之間的最大距離,(便是三角形最大邊長) gp3.setSearchRadius(200.0f); //設置各類參數值 gp3.setMu(2.5f); gp3.setMaximumNearestNeighbors(100); gp3.setMaximumSurfaceAngle(M_PI_4); gp3.setMinimumAngle(M_PI / 18); gp3.setMaximumAngle(2 * M_PI / 3); gp3.setNormalConsistency(false); //設置搜索方法和輸入點雲 gp3.setInputCloud(cloud_width_normals); gp3.setSearchMethod(tree2); //執行重構,結果保存在triangles中 gp3.reconstruct(triangles); //保存網格圖 //pcl::io::saveOBJFile("result.obj", triangles); std::string output_dir = "E:/C/cloud_mesh.ply"; std::string sav = "saved mesh in:"; sav += output_dir; pcl::console::print_info(sav.c_str()); std::cout << std::endl; pcl::io::savePLYFileBinary(output_dir.c_str(), triangles); // 顯示結果圖 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("MAP3D MESH")); ////設置背景; viewer->setBackgroundColor(0, 0, 0); //設置顯示的網格 viewer->addPolygonMesh(triangles, "my"); //viewer->initCameraParameters(); while (!viewer->wasStopped()) { viewer->spin(); } std::cout << "success" << std::endl; return 0; }
運行結果orm
說明:對象
須要處理的數據比較多,所以須要耐心等一會
三角化後的文件保存在 E:/C/cloud_mesh.ply,用compareCloud打開