【点云空间索引】python-pcl:KdTree与八叉树

news/2024/7/2 14:00:01

1. 点云是什么

通过雷达、激光扫描、立体摄像机等三维测量设备获得的点云数据,具有数据量大、分布不均匀等特点。

点云数据主要是表征目标表面的海量点集合,并不具备传统实体网格数据的几何拓扑信息。点云处理中最核心的问题就是建立离散点间的拓扑结构,实现基于邻域关系的快速查找,变的很重要。

2. 点云索引分类及应用

划分空间的索引结构有:k-d tree,八叉树、四叉树、BSP树、KDB树,R树,R+树等;

利用kdtree【k-维树】和octree【八叉树】 对海量点云进行高效压缩存储与管理,及基于邻域关系的快速搜索。

K近邻搜索操作的框架是基于FLANN(Fast Library For Approximate Nearest Neighbors)。

3. KdTree(K-维树)

在这里插入图片描述

KdTree 也称为K维树,用来组织表示K维空间中的点集合。
通常只在三个维度中处理,因此可称为3维k-d树。

KdTree、 Octree(八叉树),都是点云数据中索引的一种,为了快速索引以及无损的压缩点云而设计的。

Kd树有几种常用的搜素方法:

  • 体素内近邻搜索 (Neighbors with Voxel Search) 它把查询点所在的体素中的其他点的索引作为查询结果返回;
  • K近邻搜索(K Nearest Neighbor Serach);
  • 半径内近邻搜索(Neighbor with Radius Search)

(1) 使用最近邻方法搜索kdTree

该示例演示了

  • 1)创建kd树;
  • 2)k近邻搜索,并输出每个点的k近邻点;
  • 3)半径搜索python-pcl暂未实现。

TestCode : examples/official/kdtree/kdtree_search.py

# -*- coding: utf-8 -*-
# http://pointclouds.org/documentation/tutorials/kdtree_search.php#kdtree-searchimport numpy as np
import pcl
import randomdef main():cloud = pcl.PointCloud()# 构建点云数据points = np.zeros((1000, 3), dtype=np.float32)RAND_MAX = 1024for i in range(0, 1000):points[i][0] = 1024 * random.random() / (RAND_MAX + 1.0)points[i][1] = 1024 * random.random() / (RAND_MAX + 1.0)points[i][2] = 1024 * random.random() / (RAND_MAX + 1.0)cloud.from_array(points)# 生成k近邻树kdtree = cloud.make_kdtree_flann()# 构建一个 查询k近邻的初始点云searchPoint = pcl.PointCloud()searchPoints = np.zeros((1, 3), dtype=np.float32)searchPoints[0][0] = 1024 * random.random() / (RAND_MAX + 1.0)searchPoints[0][1] = 1024 * random.random() / (RAND_MAX + 1.0)searchPoints[0][2] = 1024 * random.random() / (RAND_MAX + 1.0)searchPoint.from_array(searchPoints)# K nearest neighbor search "K近邻搜索"K = 10  # 设置k近邻搜索 k的数量print('K nearest neighbor search at (' + str(searchPoint[0][0]) + ' ' + str(searchPoint[0][1]) + ' ' + str(searchPoint[0][2]) + ') with K=' + str(K))# 找到 searchPoint点 在指定点云中的 K 近邻[ind, sqdist] = kdtree.nearest_k_search_for_cloud(searchPoint, K)# 当k近邻搜索结果不为空时,遍历获取每个点的k近邻结果for i in range(0, ind.size):print('(' + str(cloud[ind[0][i]][0]) + ' ' + str(cloud[ind[0][i]][1]) + ' ' + str(cloud[ind[0][i]][2]) + ' (squared distance: ' + str(sqdist[0][i]) + ')')# Neighbors within radius search  "半径内近邻搜索"radius = 256.0 * random.random() / (RAND_MAX + 1.0)  # 设置半径内近邻搜索的半径值print('Neighbors within radius search at (' + str(searchPoint[0][0]) + ' ' + str(searchPoint[0][1]) + ' ' + str(searchPoint[0][2]) + ') with radius=' + str(radius))# NotImplement radiusSearch[ind, sqdist] = kdtree.radius_search_for_cloud(searchPoint, radius)print(ind.size, sqdist.size)for i in range(0, ind.size):print('(' + str(cloud[ind[0][i]][0]) + ' ' + str(cloud[ind[0][i]][1]) + ' ' + str(cloud[ind[0][i]][2]) + ' (squared distance: ' + str(sqdist[0][i]) + ')')if __name__ == "__main__":main()

(2) 用kdTree找到具体点或空间位置的k近邻

该示例演示了

  • 1)创建kd树
  • 2)找到点云1中距离点云2中每个点最近的k近邻
  • 3)也可寻找离自身点云每个点的k近邻
    TestCode : examples/official/kdtree/kdtree.py
# -*- coding: utf-8 -*-
from __future__ import print_functionimport numpy as np
import pcl#  点云1 中距离点云2中 最近的一个点及其距离 (也可搜索近邻多个)
#  也可找点云1中的k近邻 相应的还有(半径内近邻搜索)只是还未实现
def main():points_1 = np.array([[0, 0, 0],[1, 0, 0],[0, 1, 0],[1, 1, 0]], dtype=np.float32)points_2 = np.array([[0, 0, 0.2],[1, 0, 0],[0, 1, 0],[1.1, 1, 0.5]], dtype=np.float32)pc_1 = pcl.PointCloud()pc_1.from_array(points_1)pc_2 = pcl.PointCloud()pc_2.from_array(points_2)kd = pcl.KdTreeFLANN(pc_1)pc_1 = pcl.PointCloud(points_1)pc_2 = pcl.PointCloud(points_2)kd = pc_1.make_kdtree_flann()# 找到点云1中离点云2最近的一个点(就距离来说)# 可修改 找近邻数不为1 ,为2# 修改pc_2 为其自身,则是求自身每个点的近邻点indices, sqr_distances = kd.nearest_k_search_for_cloud(pc_2, 2)for i in range(pc_1.size):print('index of the closest point in pc_1 to point %d in pc_2 is %d'% (i, indices[i, 0]))print('the squared distance between these two points is %f'% sqr_distances[i, 0])if __name__ == "__main__":main()

4. Octree(八叉树)

八叉树是一种用于管理稀疏3D数据的树状数据结构,每个内部节点都正好有8个子节点。
八叉树结构通过循环递归的划分方法对大小为2n * 2n * 2n的三维空间的几何对象进行剖分,从而构成一个具有根节点的方向图。

八叉树的应用之一是点云压缩(Compression)。
八叉树也是一种索引方式,可以基于八叉树(Octrees)对点云进行空间划分和搜索操作。

在这里插入图片描述

(1) 使用八叉树进行空间分区和最近邻居搜索

该示例演示了

  • 1)创建八叉树
  • 2)找到一组点的K近邻
  • 3)找到一组点的半径近邻
  • 4)打印数据

TestCode : examples/official/octree/octree_search.py

(2) 使用八叉树来检测无序点云的空间变化

功能: 打印出数据cloudB在cloudA的基础上新增的节点;
缺点:只能探测 cloudA基础上新增的点集,并不能探测cloudA上减少的点集合

该示例演示了

  • 1)创建八叉树cloudA
  • 2)转换八叉树缓存(重置八叉树并且保留之前的结构在内存中)
  • 3)构建八叉树cloudB
  • 4)打印数据cloudB在cloudA的基础上新增的节点;

TestCode : examples/official/octree/octree_change_detection.py

5. python-pcl中支持的索引方法总结

kdTree支持 xyz、xyzi的 K近邻搜索,不支持半径近邻搜索
Octree支持 xyz的K近邻搜索,半径近邻搜索;不支持xyzi;

如下图,更清晰一些:

KdTreeOctree
xyz xyzi xyz xyzi
K近邻搜索支持支持支持不支持
半径近邻搜索不支持不支持支持不支持

参考:

  • http://pointclouds.org/documentation/tutorials/kdtree_search.php#kdtree-search
  • http://pointclouds.org/documentation/tutorials/octree.php#octree-search

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/17443.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【点云StatisticalOutlierFilter】python-pcl:去除离群点

点云去除离群点 方法:StatisticalOutlierFilter 原理:使用K近邻方法找到点云中每个点k近邻,计算出标准距离;设置俩个点之间距离超过标准距离*std倍数的为离群点。 结果:将点云分为俩部分,内点以及离群点…

Postgresql: 时间戳long,TimeStamp,Date,String互转

今天遇到一个神奇的问题:Postgre数据库里存的 10位long类型的时间戳,拿Java代码转完的日期年月日时分秒,转出来的时间和在pgAdmin里用sql转完的日期 整整差了8个小时。。。。。 你不信吗? 请看图 时间戳:1598619305 转…

Open3D DbScanClustering聚类算法及聚类分簇可视化及存储

DBSCAN聚类算法,是基于密度的聚类算法。该算法需要两个参数。 labels np.array(pcd.cluster_dbscan(eps0.02, min_points10, print_progressTrue)) 入参: eps: 定义到聚类邻居的距离min_points: 定义形成聚类所需的最小点数。 出…

端口01 - 零基础入门学习汇编语言67

第十四章:端口01 让编程改变世界 Change the world by program 引言 CPU可以直接读写3 个地方的数据 (1)CPU 内部的寄存器; (2)内存单元; (3)端口。 这一章&#xff0c…

【点云重采样Resampling】Python-pcl 基于多项式平滑点云及法线估计的曲面重建

1. 点云重采样 基于多项式平滑点云及法线估计的曲面重建以实现重采样,可以使得点云数据更规整一些,没之前那么杂乱。 set_Compute_Normals(True) 可以通过在最小二乘法中进行法线估计,提高重采样准确度;set_polynomial_fit(True…

Open3D KdTree建立、3种近邻搜索及结果可视化

1. 点云索引 Open3D KdTree,可以快速的在无序的点云中建立空间拓扑结构,使得能迅速的进行近邻搜索; 2. 近邻方法分类: Open3D这边支持的近邻搜索方法由VTK实现; K近邻搜索(K Nearest Neighbors Search)半径近邻搜索(Radius Nearest Neighbors Search)混合近邻搜索(…

Open3D 点云法向量3种估计方法及法向量可视化

点云3种法向量估计方法及可视化 1)点云读取可视化2)下采样可视化3)法向量三种估计方式(K近邻估计,半径近邻估计,混合搜索估计)4)点云每个点对应的法向量点存储及可视化5)法向量点和原始点云同时可视化6)源码1)点云读取可视化 原始点云: 2)下采样可视化 下采样:…

使用Python,OpenCV创建动画GIF图和模因生成器

在这篇博客中,我们将学习如何使用Python,OpenCV,dlib和ImageMagick工具箱创建动画GIF。 然后,您将结合所有这些技术,使用OpenCV构建一个模因生成器(眼镜👓和文字Deal with it) 效果图: 首先,讨论该项目的先决条件和依赖项,包括如何正确配置开发环境。 然后,将审…