open3d点云划分之kd树

文章目录

k-d树是一种点云划分方法,其基本思路是,对方差最差的维度进行二分分割,从而得到两个子集,再对这两个子集进行相同的操作,直到所有子集的元素个数低于设定值。

考虑到大部分使用open3d的都不算是初级用户,故而先介绍open3d中提供的接口,而后对kd树的原理进行说明。

open3d实现

import open3d as o3d
pcd = o3d.io.read_point_cloud('rabbit.pcd')
# 通过点云创建kd树
kdt = o3d.geometry.KDTreeFlann(pcd)

 
 

kd树,和其他树一样,有一个重要的功能就是提高索引速度,将原本的

     O  ( n ) O(n) 

O(n)复杂度降低到类似

     O (  ln n  )  O(\ln n) 

O(lnn)的水平。KDTreeFlann针对索引半径、索引范围,主要提供了三种索引方式

# 通过距离和最大点数来索引
search_hybrid_vector_3d(query, radius, max_nn)
# 通过点数索引
search_knn_vector_3d(self, query, knn)
# 通过半径索引
search_radius_vector_3d(self, query, radius)
# 综合索引方法, search_param为专门为kd树提供的参数对象
search_vector_3d(self, query, search_param)

 
 

对于这四种3d方法,都有一个与之对应的xd版本,可以用于更高或者更低维度的kd-tree的索引。

下面演示一下knn半径搜索的方法

pcd.paint_uniform_color([0.5, 0.5, 0.5])
k, idx, _ = kdt.search_knn_vector_3d(pcd.points[250], 200)
for i in idx:
    pcd.colors[i] = [0, 0, 1]

pcd.colors[250] = [1,0,0]

得到结果如下

在这里插入图片描述

搜索返回的参数中,k即搜索到的点数,idx为点的序号。由于knn方法指定了搜索个数为200,故k=200。相比之下,radius方法返回的点数数目就不这么确定了

pcd.paint_uniform_color([0.5, 0.5, 0.5])
k, idx, _ = kdt.search_radius_vector_3d(pcd.points[250], 0.2)
for i in idx:
    pcd.colors[i] = [0, 0, 1]

pcd.colors[250] = [1,0,0]

最终得到k=8,由于点数过少,所以下面的图单独把兔耳朵放大

在这里插入图片描述

原理

考虑到演示方便,所以用二维空间中的数据来做一点说明,假设现有六个数据点{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},如何能够通过这六个点将空间分割,就如下图一样。

在这里插入图片描述

当然上面这个图只是一种方案,或许还有其他的划分方式。

对此例来说,其分割步骤为

  1. 计算x,y方向上数据的标准差,可得
           s  x  ≈ 2.4   ,  s   y  ≈ 2.1 s_x\approx2.4,s_y\approx2.1 
    

sx2.4,sy2.1,即

       s x  > x y s_x>x_y 

sx>xy,所以先分割x方向的数据。

  • x轴方向的值为2,5,9,4,8,7,排序后为2,4,5,7,8,9,中值为7,所以先在
  •       x  =  7  x=7 
    

    x=7的位置画一条与y轴平行的线,这条线经过点(7,2),将平面分成左子空间和右子空间。

  •       x  ⩽ 7  x\leqslant7 
    

    x7的左子空间,包含3个节点{(2,3), (5,4), (4,7)};

          x >   7  x>7 
    

    x>7的右子空间,则包含2个节点{(9,6),(8,1)}。

  • 对左子空间和右子空间重复1过程,直到所有的点都画了线,最终就得到上图了。
  • 而这个生成分割图的过程,也是生成kd树的过程,其树图为

    7,2
    2,3
    5,4
    4,7
    9,6
    8,1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Open3d提供了几种点云划分的方法,包括点云下采样、点云聚类和点云分割。在点云下采样方面,Open3d提供了体素下采样、均匀下采样和随机下采样三种方法。体素下采样是通过将点云分成许多体素,并只保留每个体素中的一个点来实现下采样。均匀下采样是通过在点云中均匀采样一定数量的点来实现下采样。随机下采样是通过随机选择一定数量的点来实现下采样。 在点云聚类方面,Open3d提供了Open3d点云聚类和Sklearn点云聚类两种方法。Open3d点云聚类使用DBSCAN算法点云分成不同的聚类。Sklearn点云聚类使用K-means算法点云分成不同的聚类。 在点云分割方面,Open3d提供了RANSAC分割平面的方法。该方法可以从点云中识别出平面,并将平面内的点和平面外的点分割开来。 以上是Open3d点云划分的几种方法,可以根据具体需求选择适合的方法进行点云处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Open3d系列 | 3. Open3d实现点云上采样、点云聚类、点云分割以及点云重建](https://blog.csdn.net/weixin_44751294/article/details/127632795)[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: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值