论文阅读+代码解读
论文标题:Siamese KPConv: 3D multiple change detection from raw point clouds using deep learning
期刊:2023,ISPRS Journal of Photogrammetry and Remote Sensing
代码:https://github.com/IdeGelis/torch-points3d-SiameseKPConv
写在前面:博客内容为个人观点和个人总结,并非完全的论文翻译,如果想了解论文具体内容,请看原论文
摘要
这篇文章是点云变化检测的,主要是针对城市场景。
本文提出了一种对原始3D数据直接进行变化检测的方法(栅格化数据(Rasterized Data)会导致信息丢失,因此更倾向于使用原始3D数据)----Siamese KPConv网络.
栅格化数据(Rasterized Data)
栅格化是将点云数据转换为规则的二维或三维网格的过程。每个网格单元(称为像素或体素)包含一个或多个点的信息。在二维栅格化中,点云数据通常被投影到一个平面上,生成类似于图像的二维栅格(例如数字表面模型DSM)。在三维栅格化中,点云数据被分割成三维体素(Voxel),每个体素表示一个小立方体空间内的点云信息
introduction
3D点云变化检测(change detection)可以分为几种类型。
二分类还是多分类、点云尺度还是点尺度。
如下图所示,输入一对点云数据,类型A输出一个二进制的结果(变化/没变化),类型B不光检测到变化,对变化的物体进行了分类,New building,所以它的结果是一个多分类结果(没变化、变化的物体是什么)。但是这两个都属于点云尺度上的变化检测,因为他们的检测对象是整个点云对,输出结果是整个点云对的检测结果。
C和D则是点尺度的检测,可以看到C中对每一个点进行了分类,紫色的是没有发生改变的,黄色的是发生改变的,这其实也是一个二分类结果,但是他对每一个点都进行了二分类,这就属于针对变化的分割了。D也是对每个点的分类,但是他不是二分类,而是多个类别(没变化、new building、new clutter等)
那么这几类变化检测,我们从实用的角度很容易可以看出,D是我们想要实现的效果。因为在较大规模的点云数据中,通常物体不止一类,且变化的物体也不止一类,所以二分类的检测不能满足要求,只知道变化或者没变化对我们来说还不够,因此需要多分类的检测。并且点云尺度的检测只适用于小规模的点云数据,物体较为单一的,检测对象较为单一的情况,复杂的真实的场景还是需要点尺度上的多分类变化检测。
本文的主要贡献:
- Siamese KPConv网络:一种能够直接从原始3D点云中进行多类变化分割的深度学习方法。
- 三个新的数据集:包括合成的Urb3DCD-V2数据集及其分类版本,以及基于真实数据的AHN-CD数据集
Related work
3D点云变化检测:
现有方法分类两类:
- 后分类方法:首先对每个点云进行语义分割,然后比较不同时间点的标签以检测变化。这类方法容易累积每个步骤的误差。
- 预分类方法:直接检测变化,然后对变化进行分类。这类方法同样存在误差累积的问题。
Siamese架构:
Siamese网络最初用于计算机视觉任务,属于双流架构,由两个相同的分支组成,每个分支处理一个输入数据(如图像或点云),然后通过特征差异来检测变化。Siamese网络可以分为: - 纯Siamese网络:两个分支共享权重。
- 伪Siamese网络:两个分支不共享权重,灵活性更高,但训练参数更多。
Siamese全卷积网络(FCN)在变化检测中表现出色,通常结合U-Net架构,通过跳跃连接融合编码器和解码器的信息。
3D点云的深度学习方法:
处理3D点云的深度学习方法主要分为三类: - 基于投影的方法:将3D点云投影到2D平面(如栅格或球面),然后应用传统的2D图像处理方法。
- 基于离散化的方法:将3D点云转换为3D体素网格,便于使用3D卷积操作,但会丢失信息且计算成本高。
- 基于点的方法:直接处理原始点云,避免了投影和离散化的缺点。PointNet是这类方法的代表,能够学习逐点特征和全局特征,但其在处理大规模点云时存在局限性。
近年来,基于点卷积的方法逐渐流行,例如Kernel Point Convolution (KPConv),它在点云分割和分类任务中表现出色,尤其是在大规模城市点云数据集上。KPConv通过定义核点来对点云进行卷积操作,能够处理点云的稀疏性和不规则分布。
KPConv是一种专门为点云数据设计的卷积操作。
类似于图像,图像中的卷积操作依靠卷积核,对一定范围内的像素点进行相关运算。
KPConv定义了点云中点的卷积操作,它依赖于核点对一定范围内的点进行运算。
KPConv 使用一组核点来定义卷积权重,核点是预定义的一组点,核点的数量可以任意设置,它们的位置和形状可以自适应地进行调整。KPConv通过计算输入点云中的每个点与核点之间的关系,根据关系进行加权聚合等步骤,实现了一种适应点云数据特点的卷积操作。
关于KPConv的详细做法,可以阅读KPConv: Flexible and Deformable Convolution for Point Clouds
Method
大致的思路就是,参考2D图像变化检测,使用Siamese FCN,将其中涉及的标准2D卷积替换为3D点云卷积(KPConv),来实现点云变化检测。
如图所示,输入为两个点云,两个点云都将通过编码器,在过程中会计算两个点云的差异,其特征会保存下来,最后送入解码器。
整个结构就是一个Unet结构,
def forward(self, compute_loss = True, *args, **kwargs) -> Any:
"""Run forward pass. This will be called by both functions <optimize_parameters> and <test>."""
stack_down = [] ## 用于存储下采样阶段的中间特征,这些特征将在上采样阶段使用
# 两个输入点云的数据
data0 = self.input0
data1 = self.input1
## 遍历所有的下采样模块(编码器)--除最后一层外(后面会单独处理)
for i in range(len(self.down_modules) - 1):
## 对于每一对点云(data0 和 data1),分别通过下采样模块处理
data0 = self.down_modules[i](data0, precomputed=self.pre_computed)
data1 = self.down_modules[i](data1, precomputed=self.pre_computed_target)
# 使用 knn(k-最近邻)查找 data1 中每个点在 data0 中的最近邻点
nn_list = knn(data0.pos, data1.pos, 1, data0.batch, data1.batch)
# 计算 data1 和 data0 的特征差异(diff.x),并将差异特征存储到 stack_down 中
diff = data1.clone()
diff.x = data1.x - data0.x[nn_list[1,:]