pcl點雲聚類方法

<1>歐式聚類分割方法

//爲提取點雲時使用的搜素對象利用輸入點雲cloud_filtered創建Kd樹對象tree。

 pcl::search::KdTree<pcl::PointXYZ>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZ>);
tree->setInputCloud (cloud_filtered);//創建點雲索引向量,用於存儲實際的點雲信息

首先創建一個Kd樹對象作爲提取點雲時所用的搜索方法,再創建一個點雲索引向量cluster_indices,用於存儲實際的點雲索引信息,每個檢測到的點雲聚類被保存在這裏。請注意: cluster_indices是一個向量,對每個檢測到的聚類,它都包含一個索引點的實例,如cluster_indices[0]包含點雲中第一個聚類包含的點集的所有索引。

std::vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction ec;
ec.setClusterTolerance (0.02); //設置近鄰搜索的搜索半徑爲2cm
ec.setMinClusterSize (100);//設置一個聚類需要的最少點數目爲100
ec.setMaxClusterSize (25000); //設置一個聚類需要的最大點數目爲25000
ec.setSearchMethod (tree);//設置點雲的搜索機制
ec.setInputCloud (cloud_filtered);
ec.extract (cluster_indices);//從點雲中提取聚類,並將點雲索引保存在cluster_indices中

因爲點雲是PointXYZ類型的,所以這裏用點雲類型PointXYZ創建一個歐氏聚類對象,並設置提取的參數和變量。注意:設置一個合適的聚類搜索半徑ClusterTolerance,如果搜索半徑取一個非常小的值,那麼一個實際的對象就會被分割爲多個聚類;如果將值設置得太高,那麼多個對象就會被分割爲一個聚類,所以需要進行測試找出最適合的ClusterTolerance。本例用兩個參數來限制找到的聚類:用setMinClusterSize()來限制一個聚類最少需要的點數目,用setMaXClusterSize()來限制最多需要的點數目。接下來我們從點雲中提取聚類,並將點雲索引保存在cluster_indices中。

爲了從點雲索引向量中分割出每個聚類,必須迭代訪問點雲索引,每次創建一個新的點雲數據集,並且將所有當前聚類的點寫入到點雲數據集中。

//迭代訪問點雲索引cluster_indices,直到分割出所有聚類

int j = 0;

for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin (); it != cluster_indices.end (); ++it)
    {
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_cluster (new pcl::PointCloud<pcl::PointXYZ>);
    //創建新的點雲數據集cloud_cluster,將所有當前聚類寫入到點雲數據集中
    for (std::vector<int>::const_iterator pit = it->indices.begin (); pit != it->indices.end (); ++pit)
    {
        cloud_cluster->points.push_back (cloud_filtered->points[*pit]);
        cloud_cluster->width = cloud_cluster->points.size ();
        cloud_cluster->height = 1;
        cloud_cluster->is_dense = true; 
    }
    pcl::visualization::CloudViewer viewer("Cloud Viewer");
    viewer.showCloud(cloud_cluster);
    pause();
    }
保存每個cloud_cluster爲單獨的.pcd文件,一個文件就是一個聚類
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章