標籤:
PCL系列
- PCL系列——讀入PCD格式檔案操作
- PCL系列——將點雲資料寫入PCD格式檔案
- PCL系列——拼接兩個點雲
- PCL系列——從深度映像(RangeImage)中提取NARF關鍵點
- PCL系列——如何可視化深度映像
- PCL系列——如何使用迭代最近點法(ICP)配准
- PCL系列——如何逐漸地配准一對點雲
- PCL系列——三維重構之泊松重構
- PCL系列——三維重構之貪婪三角投影演算法
- PCL系列——三維重構之移動立方體演算法
說明
通過本教程,我們將會學會:
- 如果通過移動立方體演算法進行三維點雲重構。
- 程式支援兩種檔案格式:
*.pcd和*.ply。
- 程式先讀取點雲檔案;然後計演算法向量,並將法向量和點雲座標放在一起;接著使用移動立方體演算法進行重構,最後顯示結果。
操作
- 在VS2010 中建立一個檔案
recon_marchingCubes.cpp,然後將下面的代碼複製到檔案中。
- 參照之前的文章,設定項目的屬性。設定包含目錄和庫目錄和附加依賴項。
#include <pcl/point_types.h>#include <pcl/io/pcd_io.h>#include <pcl/io/ply_io.h>#include <pcl/kdtree/kdtree_flann.h>#include <pcl/features/normal_3d.h>#include <pcl/surface/marching_cubes_hoppe.h>#include <pcl/surface/marching_cubes_rbf.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>#include <string>int main (int argc, char** argv){ // 確定檔案格式 char tmpStr[100]; strcpy(tmpStr,argv[1]); char* pext = strrchr(tmpStr, ‘.‘); std::string extply("ply"); std::string extpcd("pcd"); if(pext){ *pext=‘\0‘; pext++; } std::string ext(pext); //如果不支援檔案格式,退出程式 if (!((ext == extply)||(ext == extpcd))){ std::cout << "檔案格式不支援!" << std::endl; std::cout << "支援檔案格式:*.pcd和*.ply!" << std::endl; return(-1); } //根據檔案格式選擇輸入方式 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>) ; //建立點雲對象指標,用於儲存輸入 if (ext == extply){ if (pcl::io::loadPLYFile(argv[1] , *cloud) == -1){ PCL_ERROR("Could not read ply file!\n") ; return -1; } } else{ if (pcl::io::loadPCDFile(argv[1] , *cloud) == -1){ PCL_ERROR("Could not read pcd file!\n") ; return -1; } } // 估計法向量 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>); tree->setInputCloud(cloud); n.setInputCloud(cloud); n.setSearchMethod(tree); n.setKSearch(20); n.compute (*normals); //計演算法線,結果儲存在normals中 //* normals 不能同時包含點的法向量和表面的曲率 //將點雲和法線放到一起 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); //初始化MarchingCubes對象,並設定參數 pcl::MarchingCubes<pcl::PointNormal> *mc; mc = new pcl::MarchingCubesHoppe<pcl::PointNormal> (); /* if (hoppe_or_rbf == 0) mc = new pcl::MarchingCubesHoppe<pcl::PointNormal> (); else { mc = new pcl::MarchingCubesRBF<pcl::PointNormal> (); (reinterpret_cast<pcl::MarchingCubesRBF<pcl::PointNormal>*> (mc))->setOffSurfaceDisplacement (off_surface_displacement); } */ //建立多變形網格,用於儲存結果 pcl::PolygonMesh mesh; //設定MarchingCubes對象的參數 mc->setIsoLevel (0.0f); mc->setGridResolution (50, 50, 50); mc->setPercentageExtendGrid (0.0f); //設定搜尋方法 mc->setInputCloud (cloud_with_normals); //執行重構,結果儲存在mesh中 mc->reconstruct (mesh); //儲存網格圖 pcl::io::savePLYFile("result.ply", mesh); // 顯示結果圖 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); viewer->setBackgroundColor (0, 0, 0); //設定背景 viewer->addPolygonMesh(mesh,"my"); //設定顯示的網格 viewer->addCoordinateSystem (1.0); //設定座標系 viewer->initCameraParameters (); while (!viewer->wasStopped ()){ viewer->spinOnce (100); boost::this_thread::sleep (boost::posix_time::microseconds (100000)); } return (0);}
- 重建項目。
- 到改項目的Debug目錄下,按住Shift,同時點擊滑鼠右鍵,在當前視窗開啟CMD視窗。
- 在命令列中輸入
recon_marchingCubes.exe bunny.points.ply,執行程式。得到如所示的結果。
PCL系列——三維重構之移動立方體演算法