PCL欧式聚类效果显示
功能:欧式聚类根据欧式距离进行聚类
缺点:两类物体间有时点云有连接,并且连接处点云密度与物体密度相似,会导致聚类失败
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL)
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/statistical_outlier_removal.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/segmentation/sac_segmentation.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/extract_indices.h>
#include<ctime>
#include<cstdlib>
#include <windows.h>
int *rand_rgb(){//随机产生颜色
int *rgb = new int[3];
rgb[0] = rand() % 255;
rgb[1] = rand() % 255;
rgb[2] = rand() % 255;
return rgb;
}
void CreateCloudFromTxt(const std::string& file_path, pcl::PointCloud<pcl::PointXYZ>::Ptr cloud)
{
std::ifstream file(file_path.c_str());//c_str():生成一个const char*指针,指向以空字符终止的数组。
std::string line;
pcl::PointXYZ point;
while (getline(file, line)) {//用到x,y,z
std::stringstream ss(line);
ss >> point.x;
ss >> point.y;
ss >> point.z;
cloud->push_back(point);
}
file.close();
}
int main(){
//------------------程序运行时间---------------------------//
clock_t start, end;
start = clock();
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
clock_t start1, end1;
start1 = clock();
CreateCloudFromTxt("ccc6.asc", cloud);
end1 = clock();
cout << "读入文件程序运行时间: " << (double)(end1 - start1) << " ms" << endl;
pcl::StatisticalOutlierRemoval<pcl::PointXYZ>sor; //离群点移除
pcl::PointCloud<pcl::PointXYZ>::Ptr sor_cloud(new pcl::PointCloud<pcl::PointXYZ>);
sor.setMeanK(10); //对每个点分析的邻近点个数设为10
sor.setInputCloud(cloud);
sor.setStddevMulThresh(1); //标准差倍数设为1,一个点的最近邻距离超过全局平均距离的一个标准差以上,就会舍弃
sor.filter(*sor_cloud);
int j = 0;
//---------------------欧式聚类---------------------------//
std::vector<pcl::PointIndices>ece_inlier;
pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
pcl::EuclideanClusterExtraction<pcl::PointXYZ> ece;
ece.setInputCloud(sor_cloud);
ece.setClusterTolerance(2); //设置近邻搜索的搜索半径为2cm
ece.setMinClusterSize(500);
ece.setMaxClusterSize(200000); //设置一个聚类需要的最大点数目
ece.setSearchMethod(tree); //设置点云的搜索机制
ece.extract(ece_inlier);
//-------------------聚类结果显示-------------------------//
//ext.setInputCloud(sor_cloud);
pcl::visualization::PCLVisualizer::Ptr viewer2(new pcl::visualization::PCLVisualizer("Result of EuclideanCluster"));
srand((unsigned)time(NULL));
//程序结束时间*********
end = clock();
cout << "程序运行时间: " << (double)(end - start) << " ms" << endl;
for (int i = 0; i < ece_inlier.size(); ++i)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_copy(new pcl::PointCloud<pcl::PointXYZ>);
std::vector<int> ece_inlier_ext = ece_inlier[i].indices;
copyPointCloud(*sor_cloud, ece_inlier_ext, *cloud_copy);//按照索引提取点云数据
std::stringstream ss1;
ss1 << "C:\\Users\\66666\\Desktop\\11\\5\\" << "EuclideanCluster_clouds" << j << ".pcd";
pcl::io::savePCDFileASCII(ss1.str(), *cloud_copy);//欧式聚类结果写出
int *rgb1 = rand_rgb();
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>rgb2(cloud_copy, rgb1[0], rgb1[1], rgb1[2]);
delete[]rgb1;
viewer2->addPointCloud(cloud_copy, rgb2, ss1.str());
j++;
}
viewer2->spin();
return 0;
}