3D Semantic-点云相关
Introduction
3D Semantic主要关注的问题是如何在3D空间中表示语义,根据3D表示的不同,语义的表示也会有所不同。例如3D表示可能包括点云表示、NeRF表示以及3D Gaussian表示等。
本系列主要关注Open Vocabulary Semantic相关工作,当然可能会混入一些其他的语义类任务,例如Closed Set Semantic Segmentation等。
作为系列开始的第一篇,首先记录一些相关资源地址:
- Open☀️3D:Open3D研讨会,其中包含相关论文的记录
- Chuan-10/awesome-language-embedded-3D-representations:3D语义嵌入的相关论文
OpenMask3D(NeurIPS2023)
OpenMask3D旨在解决开放词汇的3D Instance分割问题。现有的方法通常对3D场景中的每个点学习一个特征,这种方式可以用于执行语义分割,但是无法分离多个对象实例。而OpenMask3D提出了一种基于Instance的特征提取方法,它构建了一个pipeline,来为场景中的实例提取特征。在这种方式中,特征是实例级别的,而不是点级别的。
模型架构
pipeline
OpenMask3D的输入是场景的RGB-D照片序列以及重建出的3D点云(假设相机参数已知),输出则是预测出的一系列3D Instance Mask,以及每个Mask的特征。
OpenMask3D的Pipeline如下:
- 首先,通过预训练的3D分割模型(3D Mask Proposal Network)可以得到类别无关的3D Instance Mask。-> 对应Class Agnostic Instance Mask Proposals
- 然后需要为这些Instance Mask进行特征提取,主要分为Top K 视角提取、2D分割与裁剪、CLIP特征提取和聚合几个步骤。 -> 对应Mask-Feature Computation for Each Instance
- 这样就得到了一系列Instance Mask以及每个Mask对应的特征
Pipeline的第一步是提取类别无关的3D Instance Mask。具体来说,这一步将点云输入3D Mask Proposal Network,得到\(M\)个类别无关的Mask Proposal。这里使用的3D Mask Proposal Network实际上是一个预训练的3D Instance Segmentation Model,Mask3D,不过这个模型是在封闭词汇表上训练的。该模型的原始输出包括\(M\)个Instance Mask以及每个Mask所属的类别标签(来自训练集的封闭词汇表)。OpenMask3D则只选取了其中的Instance Mask输出,而不需要其中的类别标签。
Pipeline的第二步是为每个3D Instance Mask提取对应的特征。这一步骤的目的是计算出可以用于开放词汇概念的特征表示。
对于每个Instance Mask Proposal,首先需要选择该Instance在哪些RGB-D帧中高度可见;然后对于这些RGB-D帧,采用SAM进行2D Mask分割,基于分割结果进行Multi-Scale的裁剪;接着利用CLIP Encoder获取这些裁剪图像对应的Embedding;最后将这些Embedding聚合成为最终的Mask特征。
对于每个Instance Mask,首先需要为其在RGB-D序列中选取代表帧构成的子集。OpenMask3D采用了一种基于可见度分数Visibility Score的方式来选择Top K Views。下面公式表示了第\(i\)个Instance Mask在第\(j\)个RGB-D帧上的可见度分数: \[ s_{ij} = \frac{vis(i, j)}{\max_{j'}(vis(i,j'))} \] 其中\(vis(i,j)\)表示第\(i\)个Instance Mask在第\(j\)帧上的可见点的数量。对于Instance Mask中的每个点,都可以根据第\(j\)帧相关的相机参数将其投影到对应的图像坐标系下,得到齐次坐标表示\((u,v,w)^T\)。通过归一化的齐次坐标\(x,y\)和图像长宽的对比,可以判断该点是否在图像上。但是简单通过这种方式计算,并没有考虑到遮挡关系,因此OpenMask还采用阈值过滤的方式来判断遮挡。对于每个3D点,通过点云可以得到深度\(d\),通过上面的计算可以得到计算深度\(w\),对比这两个深度,如果\(w-d > k_{threshold}\),则表示该点被遮挡。
- 为什么\(w\)可以表示深度?
参考摄像机几何与极几何 - EverNorif中的公式,得到图像坐标系中的齐次坐标最后一维就是摄像机坐标系中的深度。
通过可见度分数,我们可以为每个Instance Mask得到\(k\)个RGB-D帧。我们需要从这些帧中提取到对应Mask的最佳图像裁剪。这一步使用SAM来完成。SAM接受prompt点作为输入,输出则是2D Mask以及相关置信度。OpenMask3D从Instance Mask的投影点中进行采样作为prompt点来运行SAM。通过SAM可以得到较好的2D Mask。然后基于这个2D Mask,OpenMask3D进行Mulit-Scale图像的剪裁。具体来说,将2D Mask的最紧密Bounding Box作为最低的Scale,然后进行多级scale处理,其他层级的Bounding Box逐渐变大,一共得到\(L\)个level的裁剪图片。
经过上面的步骤,对于每个Instance Mask,就可以得到\(k \cdot L\)个(裁剪)图像。将这些图像输入CLIP的视觉编码器中,得到CLIP图像Embedding。之后以平均池化来聚合得到Instance Mask的特征。
CLIP,全称为Contrastive Language-Image Pre-Training,对比语言-图像预训练。该模型由OpenAI推出,在4亿级别图像-文本数据对上进行训练,意在学习出更好的图像和文本表征,实现图像和文本之间的深度理解和关联。
下游任务
OpenMask3D输入一组RGBD图像序列以及3D点云,得到一系列Proposal Instance以及每个Instance的类别无关特征。基于这个特征,可以进行下游任务,例如开放词汇3D Instance分割。
OpenMask3D已经有Instance Mask,要处理开放词汇问题,则需要将文本和Instance特征建立联系。具体来说,对于文本查询\(q\),OpenMask3D将其构造成类似"a {} in a scene"的提示,然后利用CLIP计算其文本Embedding,计算该文本Embedding和每个Instance特征的余弦相似度,相似度最高的Instance则作为该文本查询的返回。
简单总结
OpenMask3D提出了一个可用于开放词汇3D Instance分割的特征提取Pipeline,它能在给定RGBD序列以及点云的情况下,输出3D Instance Mask以及每个Mask的特征。OpenMask3D首先将点云进行Instance分割,然后对于每个Instance,选取RGBD序列中的某些相关度高的帧,对帧中该对象的2D裁剪图片进行CLIP特征的提取,将所有提取的特征进行聚合之后赋给对应Instance的点云。
OpenMask3D的项目地址:OpenMask3D/openmask3d
OVIR-3D(CoRL2023)
OVIR-3D提出了一种有效的开放词汇3D Instance检索方法。给定语言查询,OVIR-3D能够基于不同Instanc和文本查询之间的特征相似性返回一组排序的3D Instance。OVIR-3D利用2D来指导3D,利用在广泛资料上训练的2D开放词汇检测器来生成2D Instance区域Proposal,然后将2D实例特征融合到3D点云上,以实现开放词汇的3D实例分割。OVIR-3D的核心贡献就是这个2D-to-3D的融合模块,它将3D区域Proposal任务视为2D Proposal的融合问题。
模型架构
OVIR-3D的输入包括点云\(X^N\)和RGB-D图像序列\(V=\{ I_1, I_2, ..., I_T\}\),其中相机参数均为已知。在推理阶段,对于给定的查询\(Q\),OVIR-3D则返回一组按照顺序排列的Mask,每个Mask都是代表点云的一个子集Mask。\(M^N = \{m_i|i \in [1, K] \}\)。下图绘制了OVIR-3D的模型流程。
首先,对于每个图像帧\(I_t\),OVIR-3D使用预训练2D开放语言模型来进行开放语义分割,得到2D的区域Proposal \(R^{2D} = \{r_1, ..., r_k\}\),同时每个区域能够得到一个文本对齐的特征\(F^{2D} = \{f^{2D}_1, ..., f^{2D}_k\}\)。OVIR-3D使用的预训练2D开放语言模型是Detic,该模型使用了多个大型数据集进行训练,在2D上能够做到较好的开放语义查询,并且在特征提取方面还是使用了CLIP。文本对齐的特征则从最终分类层之前的特征层中进行提取,最终分类的输出结果则被抛弃,只采用它的区域Proposal以及区域特征。
OVIR-3D适用的2D开放语义检测器不局限于Detic,还可以使用其他模型,不过它需要满足如下两个条件:
- 能够生成像素级别的Mask
- 能够为每个区域提供文本对齐的特征
(实际上也可以换成正常的分割模型+某种区域语义特征提取策略)
下一步,每个2D的Proposal区域都可以利用相机参数将其投影到3D点云上,得到投影3D区域\(R^{3D}\)。该3D区域可能对应的情况有两种,第一种情况是该区域能够匹配上点云中已有的3D Instance \(O=\{o_1, ..., o_b\}\),第二种情况是该区域不属于已有的任何3D Instance。当然初始点云中任何3D Instance都没有,是随着过程慢慢累积的。点云中已有的3D Instance被存放统一的内存存储\(B\)中,其中不仅存放了3D Instance \(O =\{o_1, ..., o_b\}\),还存放了每个3D Instance对应的3D特征\(F^{3D} = \{f_1^{3D}, ..., f_b^{3D}\}\)。
对于某个投影3D区域\(r_i^{3D}\),它能否匹配上现有的3D Instance \(o_j\),是通过特征相似性\(s_{ij}=\cos(f_i^{2D}, f_j^{3D})\)以及交并比\(IoU(r_i^{3D}, o_j)\)来进行的。其中每个3D Instance的特征实际上就是所有相关2D区域特征的平均,即\(f_i^{3D} = \frac{1}{n} \sum_{j=1}^n f_j^{2D}\)。如果这两个指标都大于对应的阈值,则认为3D区域能够匹配3D Instance,此时会更新Bank \(B\)中的3D Instance,匹配条件与更新操作如下: \[ \begin{aligned} s_{ij} > \theta_s(=0.75), &\quad IoU(r^{3D}_i, o_j) > \theta_{iou}(=0.25) \\ o_j:=o_j \cup r_i^{3D}, &\quad f_j^{3D}:= \frac{n}{n+1}f_j^{3D} + \frac{1}{n}f_i^{2D} \end{aligned} \] 如果投影区域不能匹配上任何一个现有的3D Instance,那么它将作为一个新的3D Instance加入\(B\)中。
上述的投影过程可能会生成冗余的3D Instance,导致低质量的分割以及不准确的数据关联。为了解决这个问题,OVIR-3D周期性(每\(T=300\)帧)对\(B\)中的3D Instance进行过滤和合并。过滤是针对3D Instance中的每个点进行的,对于每个点,可以计算其\(r_p^{det} = c_p^{o_i}/c_p^{vis}\),该值表示这个点被视为实例的一部分的次数比上它可见的次数,该值越小,表示这个点约不可靠,因此OVIR-3D删除\(r_p^{det} < \theta_{det}(=0.2)\)的点。合并则是针对3D Instance的,合并条件与上面的匹配条件相同。此外,对于两个3D Instance \(o_p, o_q\),如果\(recall(o_p, o_q) = |o_p \cup o_q| / |o_q| \ge \theta_{recall}(=0.25)\)并且\(s_{pq} \ge \theta_s\),则认为\(o_q\)大部分都包含在\(o_p\)之中,并且两个instance具有相同的特征,也可以进行合并。
最后,OVIR-3D使用简单的后处理步骤来分离3D空间中孤立的Instance,以及过滤可能是噪声的片段。具体来说,OVIR-3D对每个Instance进行DBSCAN处理来找到聚类结果,如果某个Instance的聚类结果无法相连,则将其分裂成多个Instance。
在推理方面,首先使用CLIP文本Encoder对文本查询\(q\)进行特征提取,在与每个3D Instance进行相似性比较的时候,OVIR-3D并没有采用所有相关2D区域特征的平均来代表3D Instance特征,而是对这些特征进行KMeans处理,选择其中K个聚类中心的特征来代表3D Instance的特征。最终的特征相似性,则是文本特征与这K个聚类中心的特征相似性的最大值。
简单总结
OVIR-3D输入点云和一组RGB-D图像,对于给定的查询,则可以输出一组按照相关性排序的点云Mask。它的核心在于将3D区域划分视作2D区域Proposal的合成,语义特征则来自2D区域,整个Pipeline的核心就在于2D-to-3D融合模块的设计。
OVIR-3D的局限性在于它并不是总能够合并非常大的Instance,对于较大的Instance,它可能会将其拆分成多个小Instance。另外,OVIR-3D也可能错过较为微小的物体,这是因为它们在过程中可能被视作噪声从而被移除。
OVIR-3D的项目地址为:shiyoung77/OVIR-3D
Open3DIS(CVPR2024)
Open3DIS的目标是解决3D场景中的开放词汇实例分割问题,它的对标前置工作是OpenMask3D和OVIR-3D。前者采用类别无关的分割网络来识别场景中的实例,后者则采用2D Proposal区域聚合的方式来获得3D区域Proposal。Open3DIS发现现存的方法很难识别较小尺寸的物体以及几何形状模糊的物体,它则融合了上面两个工作,提出改进的Pipeline,得到了更好的效果,解决了现有方法的局限性。这三个工作pipeline之间的对比如下:
模型架构
Open3DIS的Pipeline如下图所示,其中的核心在于如何得到最终的3D Instance Mask。它融合了两类方式,分别是通过预训练的3D实例分割网络得到3D Instance Proposal,和通过2D Proposal合并得到3D Proposal,最终将这两类方式的结果再进行融合得到最终的3D Proposal。
首先,Open3DIS使用ISBNet作为3D实例提议网络,直接输出3D点云的实例Mask,对应图中的\(4.Class-agnostic\ 3D\ Proposal\)。ISBNet是一种3D点云实例分割网络,它提出了一种实例感知的最远点采样方式对候选点进行采样,然后使用点聚合层对候选特征进行编码。作为对比,OpenMask3D使用的则是Mask3D。不过直接采用网络输出的3D Instance可能会导致丢失场景中的一些较小对象。
另一方面,Open3DIS提出了一个2D-guide-3D Instance Proposal模块,该模块能够更好地捕获场景中的较小对象。具体来说,该模块的输入包括点云\(P = \{p_n\}^N\),相关RGBD图像序列\(V\);输出则是一系列3D Instance Proposal,对应表示是多个Mask矩阵\(K_1 \times N\)。接下来介绍该模块的具体流程。
首先,Open3DIS会对点云进行预处理,将其分组为不同的Super point超点,假设超点的个数为\(U\),即\(\{q_u\}^U \in \{0, 1\}^{U\times N}\)。超点的引入能够提高后续流程的效率,后续的处理也基本都是基于超点进行的。接下来,Open3DIS采用与OVIR-3D类似的合并流程来得到初步的3D Instance Proposal。对于每帧的RGB图像,使用预训练的2D Instance分割器来对其进行分割,例如Grounding-DINO,SAM等分割模型,得到不同的2D Mask;同时对于3D点云,也使用点云的预训练网络(例如ISBNet,Mask3D)来进行特征提取。将2D Mask向点云上进行投影,计算其IoU来进行超点和Mask的对应。每个Mask取IoU最大的超点作为代表,然后利用点云特征之间的余弦相似度来进行超点之间的合并。这样对于每张Mask图都能够得到一个Mask相关的3D点云区域分割。
直接选择上面过程产生的3D区域作为3D Instance Proposal可能会导致结果的碎片化,为了解决这个问题,Open3DIS采用了一个自下而上的方式来合并来自不同帧的点云区域,以创建更加完整和连贯的3D Instance Proposal。首先,考虑帧内结果区域的合并,两个区域的合并同样基于IoU和特征相似性来进行,这样每个帧就得到一个对应的合并后的点云区域。接下来考虑帧间结果区域的合并。考虑两帧的结果区域分别为\(\{r_i\}^I,\{r_j\}^J\),合并后的结果区域为\(\{r_l\}^L\),其中\(L \le I + J\)。Open3DIS使用Agglomerative Clustering来进行合并的。根据下面的方式计算Cost矩阵\(C = \{c_{ij}\} \in \{0, 1\}^{(I+J)\times (I+J)}\): \[ c_{ij} = \mathbb{I}(o_{ij} > \tau_{ioi}) \odot \mathbb{I}(s_{ij} > \tau_{sim}) \] 其中\(\mathbb{I}(.)\)表示指示函数,\(\odot\)表示and操作,\(o_{ij},s_{ij}\)分别表示IoU和特征相似性。整个agglomerative clustering则根据Cost矩阵来迭代的进行合并,直到不能继续合并,即\(C\)中不再包含任何正元素。
agglomerative clustering是一种自底向上的聚类方法。在初始阶段,每个数据点被认为是单独的一个聚类,然后根据某种相似度度量来合并成更大的聚类,知道所有的数据点最终合并成为一个整体的聚类结构。
上面的操作可以得到两帧之间的合并结果,按照顺序次序或者分层次序进行全帧的合并,即可以得到最终的3D区域Proposal,对应图中的\(3.Augmented\ 3D \ proposals\)。
至此我们就得到了从两种不同方法得到的3D Proposal,将其进行简单合并,并利用非极大值抑制NMS来消除近似重复的Proposal,这样就得到最终的3D Instance Proposal。
在最后一个阶段,Open3DIS为每个3D Proposal提取语义特征。OpenMask3D采用选取top-k视图然后进行多尺度CLIP特征的提取,而Open3DIS则使用了一个更加合理的方案,核心思想是在top-k视图中更加频繁出现的点应该对最终的特征做出更多的贡献。具体来说,考虑\(f_{\lambda ,k}^{CLIP} \in \mathbb{R}^{D^{CLIP}}\)是从第\(\lambda\)个视图对第\(k\)个Mask抽取出的2D CLIP特征,\(v_\lambda \in \{0, 1\}^N\)是视图\(\lambda\)的可视图,\(m_k^{3D} \in \{0, 1\}^N\)则表示该Mask对应的3D Instance Proposal,最终该3D Instance对应的特征则提取为: \[ F^{CLIP} = || \sum_k(\sum_\lambda(v_\lambda * f_{\lambda, k}^{CLIP})*m_k^{3D})||_2 \]
简单总结
Open3DIS结合了OpenMask3D和OVIR-3D两个工作的优点来构建了一个新的Pipeline,利用了两类3D Proposal,包括来自预训练的3D Instance分割网络的3D Proposal,以及从2D Mask出发合并得到的3D Proposal。
MaskClustering(CVPR2024)
解决开放词汇3D Instance分割问题的一种思路是使用来自2D模型的特征,根据几何和特征相似性等指标来合并2D Mask以生成3D Instance。但是现有的基于该指标的合并方式通常缺乏跨所有帧的全局最优性。MaskClustering主要关注如何获取高质量,zero-shot的3D Instance Mask,它提出了一种称为视图共识(view consensus)的新指标,能够更好地利用多视图信息。其中的核心思想是,假设有非常多来自其他视图的Mask同时包含了某两个mask,那么就可以认为这两个mask属于同一个Instance。
模型架构
MaskClustering的Pipeline流程如下图所示。
MaskClustering的核心过程是基于视图共识的2D Mask合并过程。MaskClustering的输入同样是RGBD序列图像\(\{I_1, ..., I_T\}\)以及点云\(P\)。
首先使用类别无关的2D实例分割模型(例如CropFormer)来对每帧的图像进行分割,对图像\(I_t\)进行分割可以得到\(n_t\)个Instance,对应mask结果为\(\{m_{t,i}|i=1, 2, ..., n_t\}\)。这里的分割结果是Instance级别的全景分割Mask,即每个像素都属于某个Mask。
为了进行Mask之间的融合,MaskClustering需要构建一个Mask Graph \(G = (V, E)\),其中每个结点\(V\)表示某个Mask \(m_{t, i}\),每条边\(E\)则表示边上的两个Mask属于同一个Instance并且需要进行合并。判断两个Mask是否能够合并则会使用到论文提出的新指标,视图共识。建立了初始Mask Graph之后,就可以迭代地进行结点的合并(Mask的合并)以及边关系的更新(视图共识的更新)。最终产生的结果类似于聚类,每个聚类结果对应一个3D Instance,同时还包含了多个相关的2D Mask。基于这种3D Instance与2D Mask之间的对应关系,也就能够执行特征融合来得到最终3D Instance对应的语义特征。
论文的核心即是视图共识(view consensus)的计算方式。在介绍计算方式之前,先对一些前置定义和表示进行介绍。
对于给定的点云\(P\)以及图像序列帧索引\(t\),我们首先可以得到2D Mask \(m_{t,i}\)表示在第\(t\)帧图像中的第\(i\)个Mask,该Mask可以反投影到点云上得到对应区域\(P_{t,i}\)。这样,图像帧\(t\)对应的所有点云\(P_t=P_{t,1}\cup...\cup P_{t,i} \cup ...\cup P_{t, n_t}\),即为该帧所有Mask对应点云区域的并集。显然有关系\(P_{t,i} \subset P_t \subset P\)。
接下来是两个可见的概念。首先是点的可见性,如果点\(p \in P_t\),那么就说点\(p\)在图像帧\(t\)上可见。然后是Mask的可见性。我们考虑帧\(t'\)的Mask \(m_{t',i}\)在另一帧\(t\)上的可见性,注意这里的帧\(t',t\)表示不同帧。如果Mask \(m_{t',i}\)对应的点云区域\(P_{t',i}\)中有至少\(\tau_{vis}(=0.3)\)的点在帧\(t\)上可见,那么就认为Mask \(m_{t',i}\)在帧\(t\)上可见,并且将可见的部分记为\(P_{t',i}^t\)。考虑Mask \(m_{t',i}\)在所有其他帧上的可见性,它所有可见的帧集合记为\(F(m_{t',i})\)。
最后是点云之间的近似包含关系。如果点云\(P_i\)中有至少\(\tau_{contain}(=0.8)\)的点都在点云\(P_j\)中,则称\(P_j\)近似包含\(P_i\),记为\(P_i \sqsubset P_j\)。
引入视图共识的核心目的是判断两个Mask是否属于同一个实例。考虑两个Mask \(m_{t',i}\)和\(m_{t'',j}\),其中\(t'\)和\(t''\)可能代表相同的帧,也可能代表不同的帧。视图共识简单来说就是看在其他视图的角度下,这两个Mask是否属于同一个Instance。首先,我们找到能够同时对这两个Mask可见的所有帧,记为\(O(m_{t',i},m_{t'',j}) = F(m_{t',i}) \cap F(m_{t'',j})\),这些帧被称为观察帧,观察帧的个数为\(n(m_{t'i},m_{t'',j}) = |O(m_{t'i},m_{t'',j})|\)。考虑观察帧中的每一帧\(t\),检查它是否支持这两个Mask的合并。如果在帧\(t\)中,存在一个Mask \(m_{t,k}\),它对应的点云区域\(P_{t,k}\)能够近似包含两个Mask对应在帧\(t\)上的可见点云区域,即\(P_{t',i}^t \sqsubset P_{t,k}\)以及\(P_{t'',j}^t \sqsubset P_{t,k}\),那么就认为该帧\(t\)支持这两个Mask的合并。遍历所有观察帧,得到所有支持合并的帧数,最终视图共识\(c\)就是支持的帧数/观察帧总帧数。
简单使用循环来计算视图共识的时间复杂度相对较高。为了加快速度,可以提前计算并存储中间结果来消除冗余计算。具体实现可以参考原始论文或者代码实现。
给定所有的Mask作为结点,两两计算视图共识来构造Mask Graph。MaskClustering会合并视图共识\(c > \tau_{rate}(=0.9)\)的那些Mask,实际上也就是断开不满足视图共识阈值的那些边。同时为了避免观察帧过少导致的结果不稳定,MaskClustering还会在每一次迭代过程\(k\)中设定观察帧数目的阈值\(n_k\)。该过程迭代进行,最终得到聚类结果。
在最终的聚类结果中,每一簇表示一个3D Instance,同时每个3D Instance也包含了对应的2D Mask。MaskClustering采用OpenMask3D对应的Top-K帧的方法来获取实例特征。
简单总结
MaskClustering提出了一种新颖的指标,称为视图共识。用这个指标,我们能够判断两个Mask是否属于同一个Instance。这种方法充分地利用了其他帧的信息,基本能够做到全局最优。
MaskClustering的项目地址为:PKU-EPIC/MaskClustering