最初のシナリオで取得した点群の広い範囲は、干渉点ポイントクラウドデータ特徴抽出に起因するこれらのノイズを防止するために、点群データは、ノイズ排除するために前処理、必然的にノイズ大量の情報が存在します。ノイズ典型的にはランダムに分布した外れ値の数、以前に提案されたノイズフィルタ等の非標的点、ターゲットオブジェクトセグメンテーション方法をクラスタリングのその後の使用を介して濾過ポイントクラウド半径しようとします。しかし、あなたが興味を持っているこの時間は、クラウド上のデータに基づいて直接小さなクラスターをしようとします。レーザ走査の特性に応じて、レーザスキャンデータクラスタリングアルゴリズムの全体的なアイデアは、次のとおりです。現在の走査点と予め設定された閾値の範囲内で走査スポットの前部との間の距離と、現在の点は、走査スポットのクラスの前に収集されます。そうでない場合、現在の走査点は、新しいクラスタを播種するために設定され、点が予め設定されたシード閾値決意に従って同じクラスで走査されます。すべての点が異なるクラスを集めているまで、上記の手順を繰り返します。ポイントクラウド不規則な離散的な点のために、容易に濾過されたそのサイズクラスに小さくなる傾向がある。クラスタリングすることにより、物体境界特徴点検出点の影響を低減することができます 多くの場合、特徴抽出のために使用される検索アルゴリズム全体の範囲よりもはるかに高い小さな範囲内で、計算効率ので、曇り点はまた、加速クラスタリング特徴抽出に寄与する。
//欧式距离聚类,实现点云分割
#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++;
}
}