点云学习【1.2】法向量计算

本文介绍了如何使用PCA算法在三维点云数据中找到主要方向和法向量。首先通过PCA找出最大主成分,然后计算法向量以揭示点云的特征方向。实践步骤包括数据预处理、PCA应用和法向量的计算,最后展示变换后点云的可视化结果。

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

1.1中学习了PCA算法,其中最大主成分为投影到某方向后方差最大的方向(信息量最大的方向);而法向量为投影到某方向后,信息量最小的方向,因此需要PCA变换,将点云投影到特征值最小的方向。由于需要PCA算法,因此先把昨天的PCA算法拷贝过来。`

import open3d as o3d
import numpy as np
from pyntcloud import PyntCloud
from pandas import DataFrame

def PCA(data,correlation=False,sort=True):
    data_mean = np.mean(data,axis=0)
    data_normalize = data - data_mean
    H = np.dot(data_normalize.T,data_normalize)
    eigenvectors,eigenvalues,eigenvectors_t=np.linalg.svd(H)
    if sort:
        sort = eigenvalues.argsort()[::-1]
        eigenvalues = eigenvalues[sort]
        eigenvectors = eigenvectors[:,sort]
    return eigenvectors , eigenvalues


def main():
    #创建数组表格数据 读取txt文档
    raw_point_cloud_matrix = np.genfromtxt(r"F:\\point cloud\\三维点云课程\\3d数据集\\modelnet40_normal_resampled\\airplane\\airplane_0002.txt", delimiter=",")
    #可以理解为建立表格,类似excel,且只需要前三列数据(x,y,z)
    raw_point_cloud=DataFrame(raw_point_cloud_matrix[:,0:3])
    raw_point_cloud.columns = ['x','y','z']
    #将数据转化为open3d可以识别的格式
    point_cloud_pynt = PyntCloud(raw_point_cloud)
    #从点云中获取点
    points = point_cloud_pynt.points
    print("total points number is :"points.shape[0])
    #使用PCA分析点云主方向
    w,v = PCA(points)
    #提取前两个主分量
    point_cloud_vector = v[:,2]
    print("the main orientation of this pointcloud is :",point_cloud_vector)
    point = [[0,0,0],v[:,0],v[:,1]]
    lines = [[0,1],[0,2]]
    colors = [[1,0,0],[0,1,0]]
    line_set = o3d.geometry.LineSet(points = o3d.utility.Vector3dVector(point),lines = o3d.utility.Vector2iVector(lines))
    line_set.colors = o3d.utility.Vector3dVector(colors)
    o3d.visualization.draw_geometries([point_cloud_o3d,line_set])

下面开始计算法向量

#首先建立一个KD树
    pcd_tree = o3d.geometry.KDTreeFlann(point_cloud_o3d)
    normals = [] #存储法向量
    #由于一个点的法向量有无穷多个,因此计算一定数量最邻近点,求其法向量
    for i in range(points.shape[0]):
        [_,idx,_] = pcd_tree.search_knn_vector_3d(point_cloud_o3d.points[i],10)
        k_nearest_point = np.asarray(point_cloud_o3d.points)[idx,:]
        v,u = PCA(k_nearest_point)
        #提取最后一个成分
        normals.append(u[:,2])
    normals = np.array(normals, dtype=np.float64)
    point_cloud_o3d.normals = o3d.utility.Vector3dVector(normals)
    o3d.visualization.draw_geometries([point_cloud_o3d])

变换后点云:
在这里插入图片描述按下n键显示法向量
在这里插入图片描述

<think>嗯,用户想知道如何在Matlab中查看和处理点云数据。首先,我需要回忆一下Matlab中处理点云的相关工具包和函数。记得Matlab有一个Computer Vision Toolbox,里面包含处理点云的功能。比如pcread用来读取点云文件,pcshow用来显示点云。还有可能涉及到点云的滤波、配准、分割等处理步骤。 用户的问题涉及到数据可视化和处理,所以需要分两部分回答。先讲可视化,再讲处理。可视化方面,可能需要展示如何加载点云文件,用pcshow显示单个点云,或者用subplot同时显示多个点云。参考文献中的引用[1]提到了使用subplot来展示多个点云,这可以作为例子。另外,引用[4]提到了从txt文件读取点云数据,这也是用户可能需要的,因为有时候数据可能不是标准的PCD格式。 处理部分的话,常见的操作包括降采样、去噪、计算法向量、配准和提取特征。比如使用pcdownsample函数进行降采样,pcdenoise去噪。引用[3]提到stl文件的处理,可能和点云处理相关,但用户的问题更偏向点云,所以可能需要忽略这部分,或者简单提及。此外,引用[2]中的CheckBox组件可能在GUI设计中用到,但用户的问题可能更基础,不需要涉及GUI。 用户可能需要具体的代码示例,比如如何读取不同格式的文件,如何可视化,以及基本处理步骤。比如从PCD、LAS、TXT文件读取数据,并展示对应的代码。处理部分给出每个步骤的函数和示例代码,比如降采样使用pcdownsample,法向量用pcnormals等。 还需要注意用户可能遇到的问题,比如点云数据过大导致显示卡顿,这时候降采样可能有用。或者数据中有噪声需要去除。参考文献中的例子可以引用,比如引用[1]中的subplot方法,引用[4]中的导入txt数据。 可能还需要提到Matlab的可视化交互功能,比如旋转、缩放点云,或者使用Color属性根据强度或高度着色。引用[2]中提到了显示彩色点云,可能涉及到设置颜色映射。 最后,生成相关问题,比如如何导入不同格式的点云,如何进行点云配准,或者如何计算点云法向量。这些问题可以帮助用户进一步学习。</think>### Matlab点云数据处理与可视化分步说明 #### 一、数据读取 Matlab支持多种点云格式的读取,包括`.pcd`、`.las`、`.xyz`等格式: ```matlab % 读取标准PCD格式 ptCloud = pcread('cloud.pcd'); % 读取LAS文件(需安装Lidar Toolbox) lasReader = lasFileReader('cloud.las'); ptCloud = readPointCloud(lasReader); % 读取TXT数据(需N×3矩阵) data = importdata('cloud.txt'); % 支持剪贴板数据读取[^4] ptCloud = pointCloud(data(:,1:3)); ``` #### 二、基础可视化 1. **单点云显示**: ```matlab pcshow(ptCloud); xlabel('X'); ylabel('Y'); zlabel('Z'); view(30,45) % 设置观测角度 ``` 2. **多视图对比**: ```matlab figure; subplot(1,3,1); pcshow(ptCloud1); title('原始点云'); subplot(1,3,2); pcshow(ptCloud2); title('降采样点云'); subplot(1,3,3); pcshow(ptCloud3); title('去噪点云'); % [^1] ``` #### 三、高级可视化特性 | 可视化特性 | 代码示例 | |------------------|--------------------------------------------------------------------------| | 颜色映射 | `pcshow(ptCloud.Location, 'VerticalAxis', 'Z', 'MarkerSize', 30)` | | 强度值着色 | `pcshow(ptCloud.Location, ptCloud.Intensity)` | | 法向量显示 | `normals = pcnormals(ptCloud); quiver3(ptCloud.Location, normals)` | | 交互式选择 | 右键菜单支持测量距离、剖面分析等操作 | #### 四、核心处理技术 1. **数据预处理**: ```matlab % 降采样(体素滤波) downCloud = pcdownsample(ptCloud, 'gridAverage', 0.1); % 去噪处理 denoiseCloud = pcdenoise(ptCloud, 'Threshold', 1.2); % 平面分割 [model,inliers] = pcfitplane(ptCloud, 0.02); ``` 2. **特征计算**: ```matlab % 法向量估算 normals = pcnormals(ptCloud); % 曲率计算 curvatures = pccurvature(ptCloud); % 快速点特征直方图(FPFH) features = extractFPFHFeatures(ptCloud); ``` 3. **点云配准**: ```matlab % 粗配准(特征匹配) [tform, movingReg] = pcregisterfgr(moving, fixed); % 精配准(ICP算法) [tform, movingReg] = pcregistericp(moving, fixed); ``` #### 五、三维模型交互(STL文件) ```matlab % 读取STL模型 [vertices, faces] = stlGeneralAccess('model.stl'); % [^3] % 三维显示 patch('Vertices', vertices, 'Faces', faces,... 'FaceColor', [0.8 0.8 1.0], 'EdgeColor', 'none'); camlight; material shiny; ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值