PCL歐式聚類效果顯示
阿新 • • 發佈:2021-02-09
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; }