【PCL】PCL点云分割之欧式聚类分割


欧式聚类算法原理

欧式聚类算法基于点之间的欧式距离来对点云进行聚类。其算法流程如下:
1、初始化两个空集,一个作为备选点的点集,一个作为聚类的结果集。
2、对于每个点,计算其与其他点之间的欧式距离。
3、如果点与其他点的欧式距离小于设定的阈值,则将其加入备选点的点集。
4、从备选点的点集中选择一个点作为种子点,将其加入聚类的结果集。
5、从备选点的点集中移除种子点,并将其与种子点距离小于设定的阈值的点加入聚类的结果集。
6、重复步骤5,直到备选点的点集为空。
7、重复步骤4至步骤6,直到所有点都被聚类。
通过欧式聚类算法,可以将点云数据根据其几何特征进行聚类,从而实现对点云的分割和分析。

示例代码

#include <iostream>
#include <pcl/ModelCoefficients.h>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/sample_consensus/method_types.h>//模型定义头文件
#include <pcl/sample_consensus/model_types.h>//随机参数估计方法头文件
#include <pcl/segmentation/sac_segmentation.h>//基于采样一致性分割的类的头文件
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/features/normal_3d.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/segmentation/conditional_euclidean_clustering.h>//条件欧式聚类

int main()
{
	
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::io::loadPCDFile("./segmentTest.pcd", *cloud_in);

	if (cloud_in->empty())
	{
		std::cout << "input cloud is empty";
		return -1;
	}
	std::vector<pcl::PointIndices> clusters;
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_out(new pcl::PointCloud<pcl::PointXYZRGB>);
	//Creating the KdTree object for the search method of the extraction
	pcl::console::print_highlight("Segment by Euclidean Cluster Method!\n");
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
	tree->setInputCloud(cloud_in);

	//set parameters for EuclideanClusterExtraction
	pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
	ec.setClusterTolerance(0.2);
	ec.setMinClusterSize(500);
	ec.setMaxClusterSize(5000);
	ec.setSearchMethod(tree);
	ec.setInputCloud(cloud_in);
	ec.extract(clusters);
	std::cout << "Clusters Number :" << clusters.size() << std::endl;
	//color cloud for visualization
	if (!clusters.empty()) {
		srand(static_cast<unsigned int> (time(0)));
		std::vector<unsigned char> colors;
		for (int i_segment = 0; i_segment < clusters.size(); i_segment++) {
			colors.push_back(static_cast<unsigned char> (rand() % 256));
			colors.push_back(static_cast<unsigned char> (rand() % 256));
			colors.push_back(static_cast<unsigned char> (rand() % 256));
		}

		cloud_out->width = cloud_in->width;
		cloud_out->height = cloud_in->height;
		cloud_out->is_dense = cloud_in->is_dense;
		for (int i_point = 0; i_point < cloud_in->points.size(); i_point++) {
			pcl::PointXYZRGB point;
			point.x = *(cloud_in->points[i_point].data);
			point.y = *(cloud_in->points[i_point].data + 1);
			point.z = *(cloud_in->points[i_point].data + 2);
			point.r = 50;
			point.g = 50;
			point.b = 50;
			cloud_out->points.push_back(point);
		}

		std::vector<pcl::PointIndices>::const_iterator i_segment;
		int next_color = 0;
		for (i_segment = clusters.begin(); i_segment != clusters.end(); i_segment++) {
			std::vector<int>::const_iterator i_point;
			for (i_point = i_segment->indices.begin(); i_point != i_segment->indices.end(); i_point++) {
				int index = *i_point;
				cloud_out->points[index].r = colors[3 * next_color];
				cloud_out->points[index].g = colors[3 * next_color + 1];
				cloud_out->points[index].b = colors[3 * next_color + 2];
			}
			next_color++;
		}
	}

	//可视化
	pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3d viewer"));
	//左边窗口显示输入的点云
	int v1(0);
	viewer->createViewPort(0, 0, 0.5, 1, v1);
	viewer->setBackgroundColor(0, 0, 0, v1);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> color_in(cloud_in, 255, 255, 255);
	viewer->addPointCloud<pcl::PointXYZ>(cloud_in, color_in, "cloud_in", v1);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_in", v1);
	//右边的窗口显示分割后的点云
	int v2(0);
	viewer->createViewPort(0.5, 0, 1, 1, v2);
	viewer->setBackgroundColor(0, 0, 0, v2);
	viewer->addPointCloud<pcl::PointXYZRGB>(cloud_out, "cloud_out", v2);
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud_out", v2);

	pcl::io::savePCDFile("./segmentResult.pcd",*cloud_out);
	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
	}
	return 0;

}


测试结果

原点云

在这里插入图片描述

分割后点云

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
PCL库中的欧式聚类分割是一种通过计算点中点之间的欧氏距离来将点分割成不同的聚类的方法。在这种方法中,首先对点进行预处理,包括去除离群点和平面模型分割。然后,使用pcl::EuclideanClusterExtraction类对点进行欧式聚类分割。该类通过设置聚类的最小和最大尺寸,以及聚类的距离阈值来提取聚类。 在使用欧式聚类分割的过程中,首先对点进行预处理,包括去除离群点和平面模型分割。然后,根据设定的距离阈值,将点中的点分成不同的聚类聚类的最小和最大尺寸可以用来控制聚类的大小。最后,可以通过获取每个聚类中的点的数量,进一步分析和处理聚类。 通过使用PCL库中的欧式聚类分割方法,可以对点数据进行有效的分割聚类,从而实现对点数据的进一步分析和应用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [PCL库-欧式聚类分割-麦粒](https://download.csdn.net/download/fei_12138/87570560)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [PCL教程-点分割之欧式聚类分割](https://blog.csdn.net/luolaihua2018/article/details/120184539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shanhedian2013

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值