激光点云目标物聚类

本文介绍了激光点云目标物聚类的原理和方法,包括欧氏聚类、KD-Tree及其应用,以及如何使用PCL库进行聚类。通过聚类可以将激光雷达数据中的障碍物点云区分,有助于多目标跟踪。文章还讨论了边界框(Bounding Boxes)和PCA Boxes在点云聚类中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lidar系列文章

传感器融合是将多个传感器采集的数据进行融合处理,以更好感知周围环境;这里首先介绍激光雷达的相关内容,包括激光雷达基本介绍(本节内容),激光点云数据处理方法(点云数据显示,点云分割,点云聚类,障碍物识别实例)等。

系列文章目录

1. 激光雷达基本介绍
2. 激光点云数据显示
3. 基于RANSAC的激光点云分割
4. 点云分割入门级实例学习
5. 激光点云目标物聚类
6. 基于PCL实现欧式聚类提取
7. 激光雷达障碍物识别


目前我已经实现点云分割,分离出障碍物点云。如果可以将这些障碍物进行区分,分离出同一物体反射的点云,则将会对我们的多目标跟踪(车辆,行人,自行车等)非常有帮助。本节主要介绍激光点云聚类算法。

欧氏聚类

聚类:分离出属于同一障碍物的激光点云,比如车辆,行人等;
欧氏聚类:Euclidean clustering,根据点之间的距离进行分组关联;
KD-Tree:通过将搜索空间分块并将点云分类进不同的区域,减小了不相邻点云间的距离计算,KD-Tree数据结构通常可以将查找时间从O(n)缩短到O(log(n)),实现快速的最近邻搜索(nearest neighbors search)。

KD-Tree

KD-Tree是一种以二叉树形式表示的数据结构,在k维空间(如三维空间X, Y , Z维度)中进行维度切换对比将点插入二叉树进行存储,以便对其进行快速检索。通过区域分割来划分区域,使用欧氏聚类等算法进行聚类时最近邻搜索将极大加速。
我们将以下图包含11点的2D点云聚类进行介绍,可以看到包含3组距离较近的点。
在这里插入图片描述
首先需要将点插入KD-Tree中,主要步骤如下:

  1. 插入任一点(-6.2,7)作为树的根节点,分割x方向,下图绿线所示;
    在这里插入图片描述
  2. 插入下一点 (-6.3, 8.4),如果其x值小于根节点,插入根节点左侧,否则根节点右侧;该点分割y区域,下图红线所示;
    在这里插入图片描述
  3. 继续插入另外两点(-5.2, 7.1) ,(-5.7, 6.3),重新分割x区域。 在这里插入图片描述
    这里用于对比的(x,y)维度是根据其深度进行判断。
    在这里插入图片描述
    下图是通过直线分割好的KD-Tree,绿色划分x轴区域,红色划分y轴区域。
    在这里插入图片描述
    为改善KD-Tree的结构,可以通过X/Y交替插入中值点的方法,使树结构更加均匀,缩短搜索时间。
    以下是KD-Tree点插入的代码实现。这里通过递归调用insertHelper函数实现插入点及更新树的节点。
	void insertHelper(Node** node, unsigned int depth, std::vector<float> point, int id)
	{
   
   
		//Tree is empty
		if(*node == NULL)
			*node = new Node(point,id);
		else
		{
   
   
			//Calculate current dim
			uint cd = depth%2; //use 3 if we are working in 3 dimension(x,y,z) kdtree
			if(point[cd]<((*node)->point[cd]))
				insertHelper(&((*node)->left),depth+1,point,id);
			else
				insertHelper(&((*node)->right),depth+1,point,id);
		}
	}

	void insert(std::vector<float> point, int id)
	{
   
   
		// TODO: Fill in this function to insert a new point into the tree
		// the function should create a new node and place correctly with in the root 
		insertHelper(&root,0,point,id);
	}

KD-Tree中搜索点

所有点插入到KD-Tree中后,下一步是通过与给定的目标对比搜索最近的点。距离目标点给定距离distanceTol(目标点附近2*distanceTol区域)的点可视为可能的临近点,再计算其距离判定是否作为近邻点。KD-Tree通过将区域进行分割可以忽略部分区域的点,加快最近邻搜索过程。
在这里插入图片描述
具体实现如下:

	void searchHelper(std::vector<float> target, Node* node,int depth, float distanceTol, std::vector<int>& ids)
	{
   
   
		if(node!=NULL)
		{
   
   	
			//Below check 3 dimensions if we are working in 3 dimension(x,y,z) kdtree
			if((node->point[0]>=(target[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值