点云特征提取算法之ISS

文章介绍了点云特征提取中的ISS算法,该算法基于PCA和非极大值抑制,用于从3D点云数据中寻找稳定的特征点。ISS通过计算加权协方差矩阵并分析特征值来确定特征点,适用于三维重建、姿态估计等应用。文章还讨论了深度学习在该领域的局限性,以及传统算法如Harris和SIFT的作用。

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

点云特征提取算法之ISS

代码链接 : ISS

Github链接:有关于环境感知方面的网络介绍及代码链接



特征点的定义参考这篇博文角点(corner point)、关键点(key point)、特征点(feature point):

在图像处理中,所谓“特征点”,主要指的就是能够在其他含有相同场景或目标的相似图像中以一种相同的或至少非常相似的不变形式表示 图像或目标 ,即是对于同一个物体或场景, 从不同的角度采集多幅图片 ,如果相同的地方能够被识别出来是相同的,则这些点或块称为特征点。


[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uIjo5e7z-1682578926049)(https://file+.vscode-resource.vscode-cdn.net/e%3A/%E6%B7%B1%E8%93%9D%E5%AD%A6%E9%99%A2/%E6%B7%B1%E8%93%9D%E5%AD%A6%E9%99%A2_%E7%82%B9%E4%BA%91/hw7/image/report/1682573542379.png)]

如上图,两张不同的图之间的特征点的描述和匹配,可以用来做三维重建,姿态估计,全景图的构造以及SLAM的应用,具有极大的发展前进。


在深度学习普及之前大部分都是由传统算法提取特征点,如下图,传统算法的代表主要由通过图像特征的Harris 算法, SUSAN算法 以及SIFT ,还有基于3D点云特性本身的ISS算法。本文主要以介绍ISS算法为主

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tVYBuPQo-1682578926050)(https://file+.vscode-resource.vscode-cdn.net/e%3A/%E6%B7%B1%E8%93%9D%E5%AD%A6%E9%99%A2/%E6%B7%B1%E8%93%9D%E5%AD%A6%E9%99%A2_%E7%82%B9%E4%BA%91/hw7/image/report/1682573785163.png)]



深度学习没有普及主要原因: 特征点的描述比较模糊,可能由观察的角度决定eg去观察一辆车的时候,轮胎上的花纹可能是特征点,但是当观察角度变成整条马路上所有车之后,这些花纹就不再是特征点了。所以导致特征点的定义模糊,所以导致没有现成的数据集,所以目前的都是一些无监督的方法。



算法简介

ISS是直接针对于点云数据的特征提取方法,其思想的核心在于PCA分解之后,其最小的特征值必须要足够大。基于这个思想我们对算法进行介绍:

  1. 对点云的每个点遍历,计算其RadiusNN


  2. 每个点根据其RadiusNN表示,并由其R近邻点计算加权的协方差矩阵

    1. 权重wj构建的思想基于: 稀疏部分的点云的权重大于密集部分的点云权重,所以定义如下对于任意一个近邻点j,其对应的矩阵与点j的R近邻的个数成反比在这里插入图片描述

    2. 最终的加权协方差矩阵定义如下:

在这里插入图片描述

  1. 对协方差矩阵进行特征值分解,分别计算λ1,λ2,λ3,降序排序


  2. 计算完所有点的特征值后,进行过滤,过滤条件如下其中γ21 和 γ32都是超参数根据实验进行调整,其大致意思可以理解成,不仅仅需要λ3的值足够大,且需要λ1 λ2 和λ3个不相等:

    在这里插入图片描述

  3. 对λ3进行NMS(非极大值抑制)

    1. 根据λ3按照降序排序
    2. 取出λ3最大值作为参考点,并加入最终的结果中
    3. 对propose的点里去除掉与参考点距离小于r的点
    4. 重复步骤23,直至propose里所有点遍历完,取出最终结果则完成了NMS过程



代码实现

这里放了几个核心代码,具体代码参考github:

ISS初始化

    def __init__(self, pc , radius = 0.1, gama21 = 0.7 , gama32 =0.7 , min_lambda3 = 0.0008, min_neighbors = None):
        self.pc = pc #o3dpc
        self.tree = o3d.geometry.KDTreeFlann(pc) # KDTree
        self.point_clound = np.asarray(pc.points) 
        self.num_points = self.point_clound.shape[0]
        self.radius = radius # 计算特征点的直径
        self.gama21 = gama21
        self.gama32 = gama32
        self.min_lambda3 = min_lambda3

初始化涉及到几个超参数,包括radius , γ21 , γ32 和最小λ3的设置 以及最小近邻点的设置。

计算特征值

    def cal_eigen(self , point , idx_neighbors , w):
        #计算根据记录的加权的radius近邻协方差矩阵
        w = 1 / np.array(w) # K
        dis = self.point_clound[idx_neighbors] - point #每个点距离query_point的相对距离 , K * 3
        conv = np.dot((dis.T * w), dis) / w.sum() # 与其相对距离成反比,与其周围点的个数成反比
        #计算特征值
        values, v = np.linalg.eig(conv)
        values  = values[np.argsort(values)[::-1]]
        return values

这里实现的是加权的协方差矩阵的构造,对每个点计算其近邻点,然后每个近邻点计算近邻点的个数,从而得到权重为个数的倒数,最终乘以L2距离,得到协方差矩阵。


NMS实现

    def NMS(self):
        #对特征点按照lambda3的值进行排序
        tmp = pd.DataFrame(self.points_eigns)
        start = len(tmp)
        tmp.sort_values('l3' ,ascending=False, inplace=True)
        tmp = tmp['id'].to_numpy().tolist()

        res = [] #用于保存最后的id
        # print(len(self.radius_neighbor))
        while (tmp):
            #取出lambda3最大的点,并加入结果中,还需要删除掉自身
            query_id = tmp[0] 
            res.append(query_id)
            tmp.remove(query_id)

            #找到query点的Rnn近邻,如果出现在tmp中全部删除
            rnn_list = self.radius_neighbor[query_id]
            jiaoji = set(tmp) & set(rnn_list) 

            for i in list(jiaoji):
                tmp.remove(i)
  
        #更新下特征点的id
        self.points_eigns['id'] = res
        end = len(res)
        print("NMS: %d"%( start - end))

有关NMS步骤上面讲的比较清楚,这里类似物体检测里的NMS,通过λ3对应置信度过滤掉propose ,通过计算r近邻对应IOU过大过滤掉同一物体,最终对于聚集密集的特征点有且仅取出一个点。




效果

数据集来自modelnet40 , 下面展示几个demo

Piano

可以看到点云从1000 -> Filter(2950) -> NMS(35),整体效果我觉得还可以,保留的特征点也比较多,参数就不细调了
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

Person

可以看到点云从1000 -> Filter(6490) -> NMS(47),对于人这种不是特别规则的形状,效果我觉得差一点,如果不看原图很难恢复。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述



在稀疏点云中进行特征提取点云处理中的一个关键问题,尤其是在三维重建、目标识别和配准等应用中。由于稀疏点云的数据密度较低,传统基于密集数据的特征提取方法往往难以直接适用。以下是一些适用于稀疏点云特征提取的方法和技术: ### 3.1 ISS(Intrinsic Shape Signatures)算法 ISS 是一种经典的非深度学习点云特征提取算法,特别适用于低密度或稀疏点云。其核心思想是通过计算点云中每个点的局部几何特性,如曲率、法向量及其邻域分布,来构造特征描述子。该方法对点云的稀疏性具有一定的鲁棒性[^3]。 - **优势**:无需大量训练数据,适用于结构清晰但稀疏的点云。 - **局限**:计算复杂度较高,且在无明显几何结构的区域可能失效。 ### 3.2 FCGF(Fully Convolutional Geometric Features) FCGF 是一种基于深度学习的点云特征提取方法,采用稀疏卷积网络结构,能够有效处理稀疏点云数据。它将点云转换为稀疏体素格网,并利用全卷积网络提取高维特征描述子,具备良好的匹配精度和效率[^1]。 - **优势**:在稀疏点云上表现优异,支持端到端训练。 - **实现方式**:使用稀疏卷积库(如 MinkowskiEngine)构建网络架构,适用于大规模点云处理。 ### 3.3 PointNet 和 PointNet++ PointNet 是一种直接处理点云数据的神经网络结构,能够对点云进行分类和分割。PointNet++ 在此基础上引入了层次化特征提取机制,能够更好地捕捉局部几何信息,适用于稀疏点云中的特征建模。 - **优势**:对输入点云的顺序不敏感,适合处理无序点集。 - **技术要点**: - 使用最大池化操作聚合点特征。 - 引入局部邻域采样策略增强特征表达能力。 ### 3.4 SparseConvNet(稀疏卷积网络) SparseConvNet 是一类专为稀疏数据设计的卷积网络结构,能够在三维空间中高效地进行卷积运算,适用于稀疏点云特征提取。与传统的稠密卷积不同,它仅在非零体素上执行计算,从而节省大量内存和计算资源。 - **典型应用**:FCGF 就是基于 SparseConvNet 构建的代表性方法[^1]。 ### 3.5 Harris3D3D SIFT Harris3D 是图像中 Harris 算法在三维空间的扩展,用于检测点云中的角点特征;而 3D SIFT 则是对 SIFT 特征的拓展,能够提取具有尺度不变性的特征描述子。 - **适用场景**:适用于稀疏但具有明显几何特征的点云。 - **限制**:受点云密度影响较大,在极稀疏情况下效果下降显著[^2]。 ### 3.6 示例代码:使用 Python 实现简单的点云特征提取(基于 Open3D) ```python import open3d as o3d import numpy as np # 加载点云 pcd = o3d.io.read_point_cloud("sparse_point_cloud.ply") # 计算法线 pcd.estimate_normals(search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)) # 提取FPFH特征 fpfh = o3d.pipelines.registration.compute_fpfh_feature( pcd, o3d.geometry.KDTreeSearchParamHybrid(radius=0.25, max_nn=100) ) print("FPFH feature dimension:", fpfh.data.shape[0]) ``` 此代码展示了如何使用 Open3D 提取 FPFH(Fast Point Feature Histograms)特征,适用于稀疏点云中的特征表示。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曼城周杰伦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值