該算法用於擬合點雲中全部的平面。php
算法核心:該算法是基於點法線之間角度的比較,企圖將知足平滑約束的相鄰點合併在一塊兒,以一簇點集的形式輸出。每簇點集被認爲是屬於相同平面。ios
工做原理:區域增加是從有最小曲率值(curvature value)的點開始的。所以,咱們必須計算出全部曲率值,並對它們進行排序。這是由於曲率最小的點位於平坦區域,而從最平坦的區域增加能夠減小區域的總數。如今咱們來具體描述這個過程:算法
1.點雲中有未標記點,按照點的曲率值對點進行排序,找到最小曲率值點,並把它添加到種子點集;測試
2.對於每一個種子點,算法都會發現周邊的全部近鄰點。1)計算每一個近鄰點與當前種子點的法線角度差(reg.setSmoothnessThreshold),若是差值小於設置的閾值,則該近鄰點被重點考慮,進行第二步測試;2)該近鄰點經過了法線角度差檢驗,若是它的曲率小於咱們設定的閾值(reg.setCurvatureThreshold),這個點就被添加到種子點集,即屬於當前平面。spa
3.經過兩次檢驗的點,被從原始點雲去除。3d
4.設置最小點簇的點數min(reg.setMinClusterSize),最大點簇爲max(reg.setMaxClusterSize)。code
4.重複1-3步,算法會生成點數在min和max的全部平面,並對不一樣平面標記不一樣顏色加以區分。orm
5.直到算法在剩餘點中生成的點簇不能知足min,算法中止工做。排序
#include <pcl/segmentation/region_growing.h> #include <pcl/features/normal_3d.h> #include <pcl/visualization/cloud_viewer.h> #include <iostream> #include <vector> #include <pcl/point_types.h> #include <pcl/search/search.h> #include <pcl/search/kdtree.h> pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud <pcl::Normal>::Ptr normals (new pcl::PointCloud <pcl::Normal>); pcl::search::Search<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>); pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal> reg; reg.setMinClusterSize (50); reg.setMaxClusterSize (1000000); reg.setSearchMethod (tree); reg.setNumberOfNeighbours (30); reg.setInputCloud (cloud); //reg.setIndices (indices); reg.setInputNormals (normals); reg.setSmoothnessThreshold (3.0 / 180.0 * M_PI); reg.setCurvatureThreshold (1.0); std::vector <pcl::PointIndices> clusters; reg.extract (clusters); //以不一樣顏色顯示擬合的平面 pcl::PointCloud <pcl::PointXYZRGB>::Ptr colored_cloud = reg.getColoredCloud (); pcl::visualization::CloudViewer viewer ("Cluster viewer"); viewer.showCloud(colored_cloud); while (!viewer.wasStopped ()) { }