1. 程式人生 > >PCL點雲曲面重建(1)

PCL點雲曲面重建(1)

實驗結果

  

 (3)無序點雲的快速三角化

使用貪婪投影三角化演算法對有向點雲進行三角化,

具體方法是:

(1)先將有向點雲投影到某一區域性二維座標平面內

(2)在座標平面內進行平面內的三角化

(3)根據平面內三位點的拓撲連線關係獲得一個三角網格曲面模型.

貪婪投影三角化演算法原理:

是處理一系列可以使網格“生長擴大”的點(邊緣點)延伸這些點直到所有符合幾何正確性和拓撲正確性的點都被連上,該演算法可以用來處理來自一個或者多個掃描器掃描到得到並且有多個連線處的散亂點雲但是演算法也是有很大的侷限性,它更適用於取樣點雲來自表面連續光滑的曲面且點雲的密度變化比較均勻的情況

複製程式碼

#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>      //貪婪投影三角化演算法

int
main (int argc, char** argv)
{
  // 將一個XYZ點型別的PCD檔案開啟並存儲到物件中
  pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
  pcl::PCLPointCloud2 cloud_blob;
  pcl::io::loadPCDFile ("bun0.pcd", cloud_blob);
  pcl::fromPCLPointCloud2 (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>);  //定義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

  // 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

  //定義搜尋樹物件
  pcl::search::KdTree<pcl::PointNormal>::Ptr tree2 (new pcl::search::KdTree<pcl::PointNormal>);
  tree2->setInputCloud (cloud_with_normals);   //點雲構建搜尋樹

  // Initialize objects
  pcl::GreedyProjectionTriangulation<pcl::PointNormal> gp3;   //定義三角化物件
  pcl::PolygonMesh triangles;                //儲存最終三角化的網路模型
 
  // Set the maximum distance between connected points (maximum edge length)
  gp3.setSearchRadius (0.025);  //設定連線點之間的最大距離,(即是三角形最大邊長)

  // 設定各引數值
  gp3.setMu (2.5);  //設定被樣本點搜尋其近鄰點的最遠距離為2.5,為了使用點雲密度的變化
  gp3.setMaximumNearestNeighbors (100);    //設定樣本點可搜尋的鄰域個數
  gp3.setMaximumSurfaceAngle(M_PI/4); // 設定某點法線方向偏離樣本點法線的最大角度45
  gp3.setMinimumAngle(M_PI/18); // 設定三角化後得到的三角形內角的最小的角度為10
  gp3.setMaximumAngle(2*M_PI/3); // 設定三角化後得到的三角形內角的最大角度為120
  gp3.setNormalConsistency(false);  //設定該引數保證法線朝向一致

  // Get result
  gp3.setInputCloud (cloud_with_normals);     //設定輸入點云為有向點雲
  gp3.setSearchMethod (tree2);   //設定搜尋方式
  gp3.reconstruct (triangles);  //重建提取三角化

  // 附加頂點資訊
  std::vector<int> parts = gp3.getPartIDs();
  std::vector<int> states = gp3.getPointStates();

  // Finish
  return (0);
}

複製程式碼

 首先看一下原來的PCD視覺化檔案

對其進行三角化視覺化的結果是