PCL 条件欧氏聚类(Segmentation_ConditionalEuclideanClustering)

欧式聚类

PCL专栏目录及须知

1.原理

条件聚类是欧式聚类的拓展,除了欧式聚类的距离阈值以外,还添加了条件阈值。通过本类,可自定义距离约束以外的条件约束,然后重写比较方法,进行条件比较。

(1)进行欧式聚类(基于距离)

(2)对聚类出的结果再进行条件聚类(基于用户设定的条件属性)

以RGB颜色条件欧式聚类为例:

1)首先对如上点云,进行欧式聚类(基于距离)分割点云,得到欧式聚类之后的结果点。即下图的树1,树2,树3。

2)再对欧式聚类之后的结果点,进行依照RGB条件判断的聚类。得到最终结果(不同颜色即为不同的聚类簇)。不是既符合欧式聚类且符合条件聚类的点云点将被抛弃。

2.使用场景

条件欧式聚类使用场景较多,因为实际计算中往往不只是欧式聚类,对于欧式聚类之后的结果还要进行适用当前场景的再度分割。因此需要用到条件欧式聚类。

3.关键函数

(1)通过比较方法进行条件比较

1)重写比较方法

float threshold = 0.0;

bool conditionFunction(const pcl::PointXYZRGB& point_a, const pcl::PointXYZRGB& point_b, float a)
{
	if (point_a.r - point_b.r < threshold && point_a.g - point_b.g < threshold && point_a.b - point_b.b < threshold)
		return true;
	else
		return false;
}

2)调用比较

segmentation.setConditionFunction(&conditionFunction);

(2)其余同欧式聚类中的关键函数

4.完整代码

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/search/kdtree.h>
#include <pcl/segmentation/conditional_euclidean_clustering.h>
#include <pcl/visualization/pcl_visualizer.h> 
#include <boost/thread/thread.hpp>

float threshold = 0.0;

bool conditionFunction(const pcl::PointXYZRGB& point_a, const pcl::PointXYZRGB& point_b, float a)
{
	if (point_a.r - point_b.r < threshold && point_a.g - point_b.g < threshold && point_a.b - point_b.b < threshold)
		return true;
	else
		return false;
}

int main()
{
	/****************条件欧式聚类(以Rgb为例)********************/
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);			// 源点云
	pcl::io::loadPCDFile("D:/code/csdn/data/many_tree.pcd", *cloud);

	// 条件聚类
	threshold = 10.0;																// 条件聚类阈值
	pcl::ConditionalEuclideanClustering<pcl::PointXYZRGB> segmentation(true);		// 设置为true,即提取太大或者太小的聚类点
	segmentation.setInputCloud(cloud);
	segmentation.setConditionFunction(&conditionFunction);							// 设置条件判断函数(可类比lambda定理)
	segmentation.setClusterTolerance(1.3);											// 设置欧式聚类阈值
	segmentation.setMinClusterSize(50);												// 设置最大聚类数目
	segmentation.setMaxClusterSize(10000);											// 设置最小聚类数目
	pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>);		// 设置搜索树
	tree->setInputCloud(cloud);
	segmentation.setSearchMethod(tree);
	std::vector<pcl::PointIndices> clusterIndices;  								// 聚类结果
	segmentation.segment(clusterIndices);

	// 提取聚类后点云
	std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clustreClouds;
	for (size_t i = 0; i < clusterIndices.size(); i++)
	{
		pcl::PointCloud<pcl::PointXYZ>::Ptr cloudTemp(new pcl::PointCloud<pcl::PointXYZ>);
		pcl::copyPointCloud(*cloud, clusterIndices[i], *cloudTemp);
		clustreClouds.push_back(cloudTemp);
	}

	/****************展示********************/
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("EuclideanClusterExtraction"));
	for (size_t i = 0; i < clustreClouds.size(); i++)
	{
		pcl::RGB rgb = pcl::getRandomColor(0, 255);
		viewer->addPointCloud<pcl::PointXYZ>(clustreClouds.at(i), pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(clustreClouds.at(i), rgb.r, rgb.g, rgb.b), "clustreClouds" + i);
	}

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}

	return (0);
}

5.结果展示

原始数据

可视化结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值