1. 程式人生 > 其它 >PCL歐式聚類效果顯示

PCL歐式聚類效果顯示

技術標籤:三維點雲學習過程c++

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;
}
應用圖
效果圖