1.(基于欧式距离聚类实现的点云分割)
生活随笔
收集整理的這篇文章主要介紹了
1.(基于欧式距离聚类实现的点云分割)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先在獲取的大場景范圍下,點云中不可避免地存在大量的噪聲信息,為了防止這些噪聲點在對點云數據進行特征提取時造成干擾,對點云數據進行預處理排除噪聲干擾。噪聲通常是個數較少且散亂分布的離群點,以前嘗試過先對點云進行半徑濾波,直通濾波之類的噪聲以及非目標點的提出,再使用聚類的方法進行目標物體分割。但是本次想直接嘗試一下在有點云數據的基礎上直接進行聚類。根據激光掃描的特點,激光掃描數據的聚類算法的整體思路為:如果當前掃描點與前一個掃描點的距離在預設閾值范圍內,則當前點被聚到前一個掃描點的類中;否則,把當前掃描點設置為新的聚類種子,根據預設閾值判斷下一個掃描點是否與該種子屬于同一類。重復以上步驟,直到所有的點都被聚到不同的類中。通過聚類,可以減少物體邊界點對特征點檢測的影響,同時,對于點云中不規則的離散點,往往其所在類的尺寸較小,很容易將其濾掉。由于特征提取中常使用的搜索算法在小范圍內的計算效率也遠高于整體范圍,因此點云聚類也有助于加速特征提取。
?
//歐式距離聚類,實現點云分割
#include "pch.h"
#include <pcl/ModelCoefficients.h>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/features/normal_3d.h>
#include <pcl/kdtree/kdtree.h>
#include <pcl/sample_consensus/method_types.h>
#include <pcl/sample_consensus/model_types.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/segmentation/extract_clusters.h>
#include <iostream>
using namespace std;int
main(int argc, char** argv)
{// 申明存儲點云的對象.pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);//讀取Pcd文件if (pcl::io::loadPCDFile<pcl::PointXYZ>("C://Users//HEHE//Desktop//flange_filter3_Radius_filter2.pcd", *cloud) == -1) { PCL_ERROR("Cloudn't read file!"); return -1; } cout << "there are " << cloud->points.size()<<" points before filtering." << endl; // 建立kd-tree對象用來搜索 .pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>);kdtree->setInputCloud(cloud);// Euclidean 聚類對象.pcl::EuclideanClusterExtraction<pcl::PointXYZ> clustering;//類EuclideanClusterExtraction是基于歐式距離進行聚類分割的類clustering.setClusterTolerance(4.0);//設置在歐氏空間中所使用的搜索半徑設置的過小可能導致聚類被劃分到幾個集群,設置的過大可能將聚類進行聯通clustering.setMinClusterSize(100);// 設置聚類包含的的最小點數目clustering.setMaxClusterSize(25000); //設置聚類包含的的最大點數目clustering.setSearchMethod(kdtree);//類的關鍵成員函數clustering.setInputCloud(cloud);//指定輸入的點云進行聚類分割std::vector<pcl::PointIndices> clusters;// cluster存儲點云聚類分割的結果。PointIndices存儲對應點集的索引clustering.extract(clusters);// For every cluster...int currentClusterNum = 1;for (std::vector<pcl::PointIndices>::const_iterator i = clusters.begin(); i != clusters.end(); ++i){//添加所有的點云到一個新的點云中pcl::PointCloud<pcl::PointXYZ>::Ptr cluster(new pcl::PointCloud<pcl::PointXYZ>);for (std::vector<int>::const_iterator point = i->indices.begin(); point != i->indices.end(); point++)cluster->points.push_back(cloud->points[*point]);cluster->width = cluster->points.size();cluster->height = 1;cluster->is_dense = true;// 保存if (cluster->points.size() <= 0)break;std::cout << "Cluster " << currentClusterNum << " has " << cluster->points.size() << " points." << std::endl;std::string fileName = "C://Users//HEHE//Desktop//cluster" + boost::to_string(currentClusterNum) + ".pcd";pcl::io::savePCDFileASCII(fileName, *cluster);currentClusterNum++;}
}
?
?
?
總結
以上是生活随笔為你收集整理的1.(基于欧式距离聚类实现的点云分割)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Window10 VS17下 Openc
- 下一篇: 将pcd格式的点云数据去掉第四维度Ite