#include #include <pcl/io/ply_io.h> #include <pcl/io/pcd_io.h> #include <pcl/point_types.h> #include <pcl/kdtree/kdtree.h>
#include <pcl/segmentation/extract_clusters.h> // 欧式聚类 #include <pcl/visualization/pcl_visualizer.h> #include <boost/thread/thread.hpp> #include <pcl/segmentation/extract_clusters.h> #include <pcl/features/moment_of_inertia_estimation.h> #include <pcl/features/normal_3d.h> #include <pcl/features/boundary.h> #include <pcl/common/common.h> #include <pcl/segmentation/sac_segmentation.h> #include <pcl/filters/extract_indices.h> #include "vtkAutoInit.h" #include <pcl/visualization/cloud_viewer.h> VTK_MODULE_INIT(vtkRenderingOpenGL); // VTK was built with vtkRenderingOpenGL2 typedef pcl::PointXYZRGB PointT; typedef pcl::PointCloud PointCloud;

using namespace std; using namespace pcl; using PointT = pcl::PointXYZRGB;

int main(int argc, char** argv) { // -------------------------------------------加载点云--------------------------------------------- pcl::PointCloud::Ptr cloud(new pcl::PointCloud); if (pcl::io::loadPLYFile ("D:\DIANYUNWENJIANJIA\qiepianfenge_ply.ply", *cloud) == -1) { PCL_ERROR("Cloud reading failed."); return (-1); } cout << "检测到点云个数" << cloud->size() << endl; // -------------------------------------------欧式聚类-------------------------------------------- pcl::search::KdTree::Ptr tree(new pcl::search::KdTree); tree->setInputCloud(cloud); vectorpcl::PointIndices cluster_indices; // 创建聚类索引的容器 pcl::EuclideanClusterExtraction ec;// 欧式聚类对象 ec.setClusterTolerance(0.005); // 设置近邻搜索的搜索半径(也即两个不同聚类团点之间的最小欧氏距离) ec.setMinClusterSize(4); // 设置一个聚类需要的最少的点数目为4 ec.setMaxClusterSize(1000); // 设置一个聚类需要的最大点数目为1000 ec.setSearchMethod(tree); // 设置点云的搜索机制 ec.setInputCloud(cloud); // 设置输入点云

ec.extract(cluster_indices);               // 从点云中提取聚类,并将点云索引保存在cluster_indices中


//计算点云质心
pcl::PointCloud<PointT>::Ptr cluster_centroids(new pcl::PointCloud<PointT>);
for (std::vector<pcl::PointIndices>::const_iterator it = cluster_indices.begin(); it != cluster_indices.end(); ++it)
{
	PointT centroid(0, 0, 0);
	for (std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit)
	{
		centroid.x += cloud->points[*pit].x;
		centroid.y += cloud->points[*pit].y;
		centroid.z += cloud->points[*pit].z;
	}
	centroid.x /= it->indices.size();
	centroid.y /= it->indices.size();
	centroid.z /= it->indices.size();
	cluster_centroids->points.push_back(centroid);
}
cluster_centroids->width = cluster_centroids->points.size();
cluster_centroids->height = 1;
cluster_centroids->is_dense = true;

// Save the centroids point cloud to a PLY file
pcl::io::savePLYFileASCII("D:\\DIANYUNWENJIANJIA\\OUSHIJULEI_ply.ply", *cluster_centroids);

//------------------------------------保存聚类结果并可视化---------------------------------------
boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("planar segment"));
viewer->setBackgroundColor(0, 0, 0);
viewer->setWindowName("欧式聚类");


int begin = 0;          //定义一个计数器,用来给保存的文件命名,从1开始
for (auto it = cluster_indices.begin(); it != cluster_indices.end(); ++it)  //遍历每一个聚类,
{
	pcl::PointCloud<PointT>::Ptr cloud_cluster(new pcl::PointCloud<PointT>);  //创建一个新的点云指针用来存储每一个聚类

	for (auto pit = it->indices.begin(); pit != it->indices.end(); pit++)    //遍历当前聚类中的所有点的索引
	{
		cloud_cluster->push_back(cloud->points[*pit]);      //通过尾加法将点加入到cloud——cluster新点云中
	}

	cout << "size" << begin + 1 << ":" << cloud_cluster->size() << endl;


	Eigen::Vector4f centroid;  //创建一个四维向量容器
	pcl::compute3DCentroid(*cloud_cluster, centroid);
	std::stringstream sa;
	sa << "cluster_" << begin;
	pcl::PointXYZ center_point(centroid(0), centroid(1), centroid(2));   //确定质心点

	//viewer->addSphere(pcl::PointXYZ(centroid[0], centroid[1], centroid[2]), 0.0023, 1.0, 0.0, 0.0, sa.str());//可视化质心点
	//std::cout << "Cluster " << begin + 1 << " Centroid: (" << centroid[0] << ", " << centroid[1] << ", " << centroid[2] << ")" << std::endl;
	std::stringstream ss;                                      //定义一个字符串流,用于生成保存的ply文件名
	ss << "Euclidean_cluster_" << begin + 1 << ".ply";          //设置文件的名字
	pcl::io::savePLYFileBinary(ss.str(), *cloud_cluster);      //将当前聚类保存为ply文件
	cout << ss.str() << "保存完毕!!!" << endl;
	begin++;    //计数器+1用于给下一个文件命名



	// 可视化相关的代码
	uint8_t R = rand() % (256) + 0;
	uint8_t G = rand() % (256) + 0;
	uint8_t B = rand() % (256) + 0;
	string str;
	ss >> str;
	pcl::visualization::PointCloudColorHandlerCustom<PointT> color(cloud_cluster, R, G, B);
	viewer->addPointCloud<PointT>(cloud_cluster, color, str);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, str);

}

viewer->initCameraParameters();
viewer->setCameraPosition(0, 0, -3, 0, -1, 0, 0);
viewer->addCoordinateSystem(1.0);
while (!viewer->wasStopped())
{
	viewer->spinOnce(100);
	boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
//------------------------------------kruskal算法---------------------------------------
PointCloud::Ptr kruskal_cloud(new PointCloud);
pcl::io::loadPLYFile("D:\\DIANYUNWENJIANJIA\\OUSHIJULEI_ply.ply", *kruskal_cloud);
...
//执行kruskal算法
...
//保存kruskal算法结果
pcl::io::savePLYFileASCII("D:\\DIANYUNWENJIANJIA\\KRUSKAL_ply.ply", *kruskal_cloud);

//可视化kruskal算法结果
boost::shared_ptr<pcl::visualization::PCLVisualizer> kruskal_viewer(new pcl::visualization::PCLVisualizer("kruskal result"));
kruskal_viewer->setBackgroundColor(0, 0, 0);
kruskal_viewer->setWindowName("Kruskal算法");
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(kruskal_cloud);
kruskal_viewer->addPointCloud<pcl::PointXYZRGB>(kruskal_cloud, rgb, "kruskal_cloud");
kruskal_viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "kruskal_cloud");
kruskal_viewer->initCameraParameters();
while (!kruskal_viewer->wasStopped())
{
	kruskal_viewer->spinOnce(100);
	boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}

return (0);
#include iostream#include pclioply_ioh#include pcliopcd_ioh#include pclpoint_typesh#include pclkdtreekdtreeh #include pclsegmentationextract_clustersh 欧式聚类#include pclvisualizationpcl

原文地址: https://www.cveoy.top/t/topic/h1yS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录