首页 > 其他分享 >Open3D 计算点云的面状指数

Open3D 计算点云的面状指数

时间:2024-08-24 11:22:55浏览次数:14  
标签:特征值 planarity 邻域 面状 Open3D 点云 pcd

目录

一、概述

1.1原理

1.2实现步骤

步骤 1:确定邻域点

步骤 2:计算协方差矩阵

步骤 3:特征值分解

步骤 4:计算面状指数

步骤 5:可视化与应用

1.3应用领域

二、代码实现

2.1关键函数

2.2完整代码

三、实现效果

3.1原始点云

3.2面状指数可视化


Open3D点云算法汇总及实战案例汇总的目录地址:

Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客


一、概述

        面状指数(Planarity Index)是分析点云局部几何形态的一种重要指标,主要用于评估点云中各点的邻域是否呈现平面结构。它在三维点云数据处理中具有广泛的应用,如特征提取、地形分析、建筑扫描、机器人导航等。

1.1原理

        面状指数通过对点云中每个点的邻域点集合进行特征值分解来评估该点邻域的平面性。具体来说,面状指数基于邻域点的协方差矩阵的特征值来计算。特征值的大小反映了点云在不同方向上的扩展程度:

  • 最大特征值(λ3):对应于点云在主方向上的扩展程度。如果该特征值远大于其他特征值,表示点云在这一方向上有显著的扩展。
  • 中间特征值(λ2):表示点云在次主方向上的扩展程度。
  • 最小特征值(λ1):表示点云在第三个方向上的扩展程度。如果该值很小,说明点云在这个方向上几乎没有扩展。

通过特征值的大小和关系,可以判断点云在局部区域的几何形态:

  • 如果 λ1 ≈ λ2 ≪ λ3,则该区域更像是一个平面,面状指数较高。
  • 如果 λ1 ≈ λ2 ≈ λ3,则该区域呈现的是一个均匀的立体结构,面状指数较低。

1.2实现步骤

步骤 1:确定邻域点

        对于点云中的每一个点 p,找到其 k 个最近邻点。这些邻域点用于评估 p 所在局部区域的几何形态。邻域的选择通常使用 KD-Tree 数据结构来加速最近邻搜索。

步骤 2:计算协方差矩阵

        对于每个点 p 的邻域点集合,计算这些点的协方差矩阵。协方差矩阵是通过邻域点相对于质心的偏移量来计算的,定义如下:

步骤 3:特征值分解

        对协方差矩阵 C 进行特征值分解,得到三个特征值 λ1、λ2、λ3,且满足 λ 1≤λ 2≤λ 3

λ1:最小特征值,对应点云在最小扩展方向上的伸展程度。

λ2:中间特征值,对应点云在中等扩展方向上的伸展程度。

λ3:最大特征值,对应点云在最大扩展方向上的伸展程度。

步骤 4:计算面状指数

面状指数通过以下公式计算:

该指数度量了点云在该区域内是否具有明显的平面性:

  • 高面状指数:表示该点的邻域在局部区域内接近于一个平面(即 λ1和 λ2相近,且远小于 λ3。)
  • 低面状指数:表示该点的邻域在局部区域内是一个立体结构,或者是沿一个方向的线状结构。

步骤 5:可视化与应用

        计算得到的面状指数可以通过颜色映射可视化,以便分析点云中的平面区域。高面状指数的区域通常代表平面结构,例如建筑物的墙面、地面等。

1.3应用领域

  • 建筑扫描:识别建筑物的墙面、屋顶等平面结构。
  • 地形分析:在地形数据中识别平坦的区域,如平原、道路等。
  • 机器人导航:识别机器人行驶的平面区域,有助于路径规划。
  • 三维重建:在三维重建中分离出平面结构,以便精细重建。

二、代码实现

2.1关键函数

def compute_planarity(pcd, k=30):
    """
    计算点云的面状指数(Planarity Index)。

    参数:
    pcd (open3d.geometry.PointCloud): 输入点云。
    k (int): 每个点的邻域点数量。

    返回:
    np.ndarray: 面状指数数组,长度与点云中的点数相同。
    """
    # 使用 KD-Tree 来查找每个点的邻域
    pcd_tree = o3d.geometry.KDTreeFlann(pcd)
    planarity_indices = np.zeros(len(pcd.points))

    # 遍历每个点,计算其面状指数
    for i in range(len(pcd.points)):
        # 查找邻域点
        [_, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[i], k)
        neighbors = np.asarray(pcd.points)[idx, :]

        # 计算协方差矩阵
        cov_matrix = np.cov(neighbors.T)

        # 计算特征值
        eigenvalues, _ = np.linalg.eigh(cov_matrix)

        # 对特征值排序
        eigenvalues = np.sort(eigenvalues)

        # 计算面状指数 (Planarity Index)
        planarity_index = (eigenvalues[1] - eigenvalues[0]) / eigenvalues[2]
        planarity_indices[i] = planarity_index

    return planarity_indices

2.2完整代码


import open3d as o3d
import numpy as np
from matplotlib import pyplot as plt


def compute_planarity(pcd, k=30):
    """
    计算点云的面状指数(Planarity Index)。

    参数:
    pcd (open3d.geometry.PointCloud): 输入点云。
    k (int): 每个点的邻域点数量。

    返回:
    np.ndarray: 面状指数数组,长度与点云中的点数相同。
    """
    # 使用 KD-Tree 来查找每个点的邻域
    pcd_tree = o3d.geometry.KDTreeFlann(pcd)
    planarity_indices = np.zeros(len(pcd.points))

    # 遍历每个点,计算其面状指数
    for i in range(len(pcd.points)):
        # 查找邻域点
        [_, idx, _] = pcd_tree.search_knn_vector_3d(pcd.points[i], k)
        neighbors = np.asarray(pcd.points)[idx, :]

        # 计算协方差矩阵
        cov_matrix = np.cov(neighbors.T)

        # 计算特征值
        eigenvalues, _ = np.linalg.eigh(cov_matrix)

        # 对特征值排序
        eigenvalues = np.sort(eigenvalues)

        # 计算面状指数 (Planarity Index)
        planarity_index = (eigenvalues[1] - eigenvalues[0]) / eigenvalues[2]
        planarity_indices[i] = planarity_index

    return planarity_indices

# 加载点云
pcd = o3d.io.read_point_cloud("standford_cloud_data\Armadillo.pcd")
o3d.visualization.draw_geometries([pcd],window_name="原始点云",width=1024,height=768,)
# 计算点云的面状指数
planarity_indices = compute_planarity(pcd)

# 可视化面状指数(使用颜色映射)
colors = plt.get_cmap("viridis")(planarity_indices / max(planarity_indices))
pcd.colors = o3d.utility.Vector3dVector(colors[:, :3])

# 显示点云和面状指数
o3d.visualization.draw_geometries([pcd],window_name="处理后点云",width=1024,height=768,)

三、实现效果

3.1原始点云

3.2面状指数可视化

标签:特征值,planarity,邻域,面状,Open3D,点云,pcd
From: https://blog.csdn.net/qq_47947920/article/details/141292078

相关文章

  • (2-2-2)LiDAR激光雷达传感器感知:点云处理(2)法向量估计(Normal Estimation)+曲面重建(Surface
    2.2.4 法向量估计(NormalEstimation)算法法向量估计的目的是计算每个点的法向量,用于后续任务如曲面重建和特征提取。常用的法向量估计(NormalEstimation)算法如下所示。1.最小二乘法(LeastSquares)算法最小二乘法(LeastSquares)算法通过最小化点云到法向量的误差来估计法向......
  • Docker+Win11:显示Docker中的GUI,解决报错“[Open3D WARNING] GLFW Error: X11: Failed
        在本系列博文中,我将Pytorch部署在Win11为宿主的Docker中,并成功的调用GPU进行了训练。这为我提供了很多便利。    今天在进行3D相关的深度学习研究时我遇到了一些问题:[Open3DWARNING]GLFWError:X11:Failedtoopendisplay:0[Open3DWARNING]Faile......
  • open3d python 法线估计
    测试效果废话Open3D中的法线估计是一个重要的功能,它可以帮助用户了解三维点云中每个点的局部表面方向。以下是对Open3D法线估计的详细解释:一、法线估计的基本原理法线估计通常基于局部表面拟合的方法。在点云数据中,每个点的局部邻域可以视为一个平面或曲面的近似。通......
  • 点云_图像--坐标中心和角点
    图像2D框boundingbox目标框(boundingbox)来描述目标的位置,目标框是矩形的。由矩形左上角的坐标(x1,y1)以及右下角的坐标(x2,y2)进行表示。另外,还可以采用边界框矩形的中心坐标(xc,yc)以及宽高(w,h)进行表示(1)"左上-右下"转换为"中心-宽高"defbox_corner_to_center(boxes):......
  • Open3d Create_from_cloud_alpha_shape 错误:无效的 unordered_map
    我在open3d中的create_from_point_cloud_alpha_shape方面遇到问题。这是我的代码。importopen3daso3dimportnumpyasnpmesh=o3d.io.read_triangle_mesh('Bunny.stl')print(mesh)pcd=mesh.sample_points_poisson_disk(750)alpha=0.3mesh=o3d.geome......
  • Open3D 三维重建-Delaunay Triangulation (德劳内三角剖分)
    目录一、概述1.1原理1.2实现步骤1.3应用二、代码实现2.1关键函数2.2完整代码三、实现效果3.1原始点云3.2重建后点云Open3D点云算法汇总及实战案例汇总的目录地址:Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客一、概述        德劳内三角剖......
  • Open3D 三维重建-Alpha Shapes (α-形状)
    目录一、概述1.1原理1.2实现步骤二、代码实现2.1关键函数2.1.1函数2.1.2参数详解2.2完整代码三、实现效果3.1原始点云3.2处理后点云Open3D点云算法汇总及实战案例汇总的目录地址:Open3D点云算法与点云深度学习案例汇总(长期更新)-CSDN博客一、概述      ......
  • Halcon学习——显示查看两点云差异
    dev_open_window_fit_size(0,0,800,800,-1,-1,WindowHandle)打开窗口 read_object_model_3d('D:/wechat/chatfile/WeChatFiles/wxid_yuyesap6fm5t22/FileStorage/File/2024-08/pointCloud.ply','m',[],[],ObjectModel3D,Status)read_obje......
  • 激光点云去畸变_原理及实现
    激光点云去畸变:原理及实现机械式激光雷达产生畸变的原因Lidar扫描周期内(一般0.1s)自车有一定幅度的旋转(Rotation)和平移(Translation),因此不同时间点打出去的激光点束并不在严格统一的Lidar坐标系内,需要对同一帧Lidar转化在统一时间戳对应的Lidar坐标系上(一般转化到第......
  • 复现opendrivelab的“点云预测”项目
    本文的主要工作就是复现下述论文中的算法。该论文全称:VisualPointCloudForecasting论文内容在此不做过多介绍,直接上项目。一、准备工作首先通读readme.md文件的内容,了解所需要的相关依赖和数据等内容。一定要多读几遍,不要扫一眼就过了。接下来就是部署环境,根据readme......