论文阅读《SuperGlue: Learning Feature Matching with Graph Neural Networks》

论文地址:https://arxiv.org/abs/1911.11763
代码地址:https://github.com/magicleap/SuperGluePretrainedNetwork


背景

  SuperGlue是一个特征匹配与外点剔除的网络,使用GNN网络来对兴趣点进行特征增强,最后将特征匹配问题等价于求解可微分最优化转移问题;受到Transformer的启发,在GNN网络中作者提出了一个自注意力机制与交叉注意力机制来抽取同一幅图内特征点间的融合信息与两幅图之间的特征点的视觉关联信息,该模型的输入为图像对的特征点与描述符,输出为图像特征之间的匹配关系;
在这里插入图片描述


模型结构

在这里插入图片描述
  模型大致分为两个部分:基于Attention GNN 的特征增强模块最优匹配模块;其中基于注意力GNN的模块将特征点的位置信息与描述子信息编码后进行特征融合,再通过self attention与cross attention来交替增强(L轮),得到用于匹配的特征匹配向量 f f f ,最优匹配层通过计算特征匹配向量的内积得到匹配度得分矩阵,然后通过Sinkhorm算法迭代得到最优特征分配矩阵;
  对于两张图像 A 、 B A、B AB 经过一个特征提取器得到特征点位置 ( x , y ) (x, y) (x,y)、每个特征点的置信度 c c c 与描述子向量 d d d ,采用以下的记法:
i i i 个特征表示为 p i : = ( x , y , c ) p_{i} := (x, y, c) pi:=(x,y,c) ,用 ( p , d ) (p, d) (p,d) 来表示 p p p 点对应的描述符,其中 d ∈ R D d\in R^{D} dRD D D D 表示描述符特征的长度;SuperGlue的特征可以是传统算法得到的特征,也可以是深度特征,在原文中采用的是 SuperPoint 得到的特征点与描述符;假设A图中包含 M M M 个特征,B图中包含 N N N 个特征;

Attention GNN模块

  Attention GNN 模块主要包含KeyPoint Encoder部分与 Attention Aggregation两个部分,其中KeyPoint Encoder部分主要将特征点位置置信度与描述子特征进行融合,得到更具有特异性的匹配特征,这个匹配特征能同时包含其位置信息与外观信息;Attention Aggregation 主要主要利用自注意力与交叉注意力机制,基于迭代优化的策略来得到更加具有特异性的匹配特征;
在这里插入图片描述

KeyPoint Encoder

  对于SuperGlue输入的第i个特征 p i p_{i} pi 与其描述子 d i d_{i} di ,通过一个多层感知机将其融合如式1所示:
( 0 ) x i = d i + M L P enc  ( p i ) (1) { }^{(0)} \mathbf{x}_{i}=\mathbf{d}_{i}+\mathbf{M L} \mathbf{P}_{\text {enc }}\left(\mathbf{p}_{i}\right)\tag{1} (0)xi=di+MLPenc (pi)(1)
其中 ( 0 ) x i { }^{(0)} \mathbf{x}_{i} (0)xi 表示迭代开始前的 i i i 点的匹配初始特征;

Multiplex Graph Neural Network

  图像A与图像B的每个特征点为一个节点,对于图内的特征点之间的无向边记为 E self  \mathcal{E}_{\text {self }} Eself  ,A与B之间的特征点之间的无向边记为 E cross \mathcal{E}_{\text {cross}} Ecross; 记 ( ℓ ) X i A {}^{(\ell)} \mathbf{X}_{i}^{A} ()XiA 为图像 A 上的第 i i i 个特征点在第 ℓ \ell 层(轮迭代)的特征向量,信息 m E → i \mathbf{m}_{\mathcal{E} \rightarrow i} mEi 为进行了一轮自注意力或交叉注意力聚合后得到的残差信息(源码中在 ℓ \ell 奇数层进行图像内的自注意力特征融合,在 ℓ \ell 为偶数层进行图像间的交叉注意力特征融合), ( ℓ ) X i A {}^{(\ell)} \mathbf{X}_{i}^{A} ()XiA根据式2来更新:
( ℓ + 1 ) x i A = ( ℓ ) x i A + MLP ⁡ ( [ ( ℓ ) x i A ∥ m E → i ] ) (2) { }^{(\ell+1)} \mathbf{x}_{i}^{A}={ }^{(\ell)} \mathbf{x}_{i}^{A}+\operatorname{MLP}\left(\left[{ }^{(\ell)} \mathbf{x}_{i}^{A} \| \mathbf{m}_{\mathcal{E} \rightarrow i}\right]\right)\tag{2} (+1)xiA=()xiA+MLP([()xiAmEi])(2)
其中 E ∈ { E s e l f , E c r o s s } \mathcal{E}\in \{\mathcal{E}_{self}, \mathcal{E}_{cross}\} E{Eself,Ecross} [ . ∣ ∣ . ] [.||.] [..] 表示拼接,图像B的特征点的更新方式与A相似,故不赘述;这个步骤也是参照人类进行特征匹配的过程:先在左图中观察每个特征点与周围特征点的相对关系,再在右图中观察,然后再对比观察两幅图像中特征点的相对关系;

Attentional Aggregation

注意力机制:对于信息残差值 m E → i \mathbf{m}_{\mathcal{E} \rightarrow i} mEi,有:
m E → i = ∑ j : ( i , j ) ∈ E α i j v j (3) \mathbf{m}_{\mathcal{E} \rightarrow i}=\sum_{j:(i, j) \in \mathcal{E}} \alpha_{i j} \mathbf{v}_{j}\tag{3} mEi=j:(i,j)Eαijvj(3)
其中 a i j a_{ij} aij 为 查询索引 query( i i i 特征)与待查询键值key( j j j 特征)的相似度,上式表示用于更新 i i i 特征的信息是聚合了所有 j j j 特征集合的信息而来(因为 value 的下标为 j j j),而相似度 a i j a_{ij} aij 是根据 i i i 特征集合与 j j j 特征集合取出的特征的相似度计算来,即:
α i j = Softmax ⁡ j ( q i ⊤ k j ) (4) \alpha_{i j}=\operatorname{Softmax}_{j}\left(\mathbf{q}_{i}^{\top} \mathbf{k}_{j}\right)\tag{4} αij=Softmaxj(qikj)(4)
q i 、 k i 、 v i q_{i} 、k_{i} 、v_{i} qikivi 由以下的方式计算而来, Q表示特征 i i i 所在的图像(query图像), S表示特征 j j j 特征所在的图像(source图像):
q i = W 1 ( ℓ ) x i Q + b 1 [ k j v j ] = [ W 2 W 3 ] ( ℓ ) x i S + [ b 2 b 3 ] (5) \begin{aligned} \mathbf{q}_{i} &=\mathbf{W}_{1}^{(\ell)} \mathbf{x}_{i}^{Q}+\mathbf{b}_{1} \\\\ {\left[\begin{array}{c} \mathbf{k}_{j} \\ \mathbf{v}_{j} \end{array}\right] } &=\left[\begin{array}{l} \mathbf{W}_{2} \\ \mathbf{W}_{3} \end{array}\right]{}^{(\ell)} \mathbf{x}_{i}^{S}+\left[\begin{array}{l} \mathbf{b}_{2} \\ \mathbf{b}_{3} \end{array}\right] \end{aligned}\tag{5} qi[kjvj]=W1()xiQ+b1=[W2W3]()xiS+[b2b3](5)
在源码中: q i = M L P 1 ( ( ℓ ) x i Q ) k j = M L P 2 ( ( ℓ ) x i S ) v i = M L P 3 ( ( ℓ ) x i S ) q_{i}=MLP_{1}({}^{(\ell)}x_{i}^{Q})\\\\k_{j}=MLP_{2}({}^{(\ell)}x_{i}^{S})\\\\v_{i}=MLP_{3}({}^{(\ell)}x_{i}^{S}) qi=MLP1(()xiQ)kj=MLP2(()xiS)vi=MLP3(()xiS)
自注意力特征融合:在 ℓ \ell 层为奇数时进行自注意力特征聚合,此时 Q 与 S 是同一幅图像,特征 i i i 与特征 j j j 来源于同一幅图像, 先经过多层感知机对输入的匹配特征进行特征映射;然后通过式 4 逐一计算同一幅图像内每个特征点剩余所有特征点的相似性矩阵,再根据式 3 来计算Q内其余特征点能给 i i i 点提供的信息残差值,最后通过式 2 来更新信息;
交叉注意力特征融合:在 ℓ \ell 层为偶数时进行交叉注意力特征聚合,此时 Q 与S 是表示左右视图的图像,特征 i i i 与特征 j j j 来源于两幅不同图像, 先经过多层感知机对输入的匹配特征进行特征映射;然后通过式 4 来逐一计算 Q 图像的每个特征点S 图像所有特征点的相似性矩阵,再根据式 3 计算 S 图像的所有特征点能提供给 Q 图像的第 i i i 个特征点的信息残差值,最后通过式2来更新Q图像特征点的信息;
在这里插入图片描述
  原文中展示了迭代优化的结果,其中绿色代表匹配较容易的点,蓝色代表难度中等的点,红色代表困难的点;上方两幅图表示最后结果的匹配与关键点检测情况;
  左下方的图代表在不同轮次的self attention迭代过程中,同幅图像内的特征点与其余特征点的权重关系 a i j a_{ij} aij ,在开始迭代时,图像上的特征点与全图中较多特征点都较相似,注意力比较分散(此时的特征不具有特异性),随着迭代次数增加,每个特征与其余特征的相似性逐渐降低(特征特异性增强);
  右下方代表 cross attention 迭代过程,一开始左图中的特征点与右图中较多的特征点相似性较高(注意力分散),随着迭代进行,最后左图中的特征点只与右图中的真正匹配点的相似度较高(注意力集中) ;
  上述过程说明在自注意力模块与交叉注意力模块迭代优化过程中,可以提高特征的特异性,得到的增强后的匹配特征不仅包含原有的位置与外观信息,还包含了与其余特征点融合的信息;
  对于图像 A 经过 L 轮自我注意力与交叉注意力迭代优化后,得到GNN模块的输出,如式6所示:
f i A = W ⋅ ( L ) x i A + b , ∀ i ∈ A (6) \mathbf{f}_{i}^{A}=\mathbf{W} \cdot{ }^{(L)} \mathbf{x}_{i}^{A}+\mathbf{b}, \quad \forall i \in \mathcal{A}\tag{6} fiA=W(L)xiA+b,iA(6)
其中 f i A f_{i}^{A} fiA 表示 A 图中的第 i i i 个特征点增强后的特征,这个特征用于之后的匹配;

最优匹配模块

  对于两个特征点集的匹配问题,可以试视为一个分配问题:一般通过计算分配矩阵(assignment matrix) P ∈ R M × N P\in R^{M\times N} PRM×N与得分矩阵 S ∈ R M × N S\in R^{M\times N} SRM×N 来构建优化问题,通过最大化总体得分 ∑ i , j S i , j P i , j \sum_{i, j} \mathbf{S}_{i, j} \mathbf{P}_{i, j} i,jSi,jPi,j 来求解P,优化问题描述如下:

{ m a x ( ∑ i , j S i , j P i , j ) s . t .     P 1 N ≤ 1 M  and  P ⊤ 1 M ≤ 1 N (7) \begin{cases} max(\sum_{i,j}S_{i,j}P_{i,j}) \\ s.t.\ \ \ \mathbf{P} \mathbf{1}_{N} \leq \mathbf{1}_{M} \quad \text { and } \quad \mathbf{P}^{\top} \mathbf{1}_{M} \leq \mathbf{1}_{N} \end{cases}\tag{7} {max(i,jSi,jPi,j)s.t.   P1N1M and P1M1N(7)
其中 P P P 矩阵为稀疏矩阵,两个约束表示 P P P 矩阵每一行或每一列只有一个元素为1,表示一个特征点只能与一个特征点匹配(避免一对多的匹配), P i , j = 1 P_{i, j}=1 Pi,j=1 表示A图中第 i i i 点与 B 图中的 j j j 点匹配;
  文中使用GNN输出的 f i A 与 f i B f_{i}^{A} 与 f_{i}^{B} fiAfiB 来计算得分矩阵S如式8所示:
S i , j = < f i A , f j B > ,   ∀ ( i , j ) ∈ A × B (8) \mathbf{S}_{i, j}=<\mathbf{f}_{i}^{A}, \mathbf{f}_{j}^{B}>,\ \forall(i, j) \in \mathcal{A} \times \mathcal{B}\tag{8} Si,j=<fiA,fjB>, (i,j)A×B(8)
注:与SuperPoint学习的视觉描述符不同,此处的匹配描述符 f i A 与 f i B f_{i}^{A} 与 f_{i}^{B} fiAfiB 没有归一化,其大小可以在每个特征和训练过程中变化,以反映预测的置信度。
在这里插入图片描述
借鉴SuperPoint的思想,在得分矩阵S最后的维度扩充一个dustbin通道(dustbin通道初始化为全部1,通过梯度下降继续优化),用于表示无匹配的特征点(遮挡点):
S ‾ i , N + 1 = S ‾ M + 1 , j = S ‾ M + 1 , N + 1 = z ∈ R (9) \overline{\mathbf{S}}_{i, N+1}=\overline{\mathbf{S}}_{M+1, j}=\overline{\mathbf{S}}_{M+1, N+1}=z \in \mathbb{R}\tag{9} Si,N+1=SM+1,j=SM+1,N+1=zR(9)
增加dustbin的过程类似于引入松弛变量的过程,为了使 式7 中的约束等价,引入dustbin后的软分配矩阵的约束如式10所示(原文中为等号,个人理解应该是原文写错了,此处应该为≤):
P ‾ 1 N + 1 ≤ a  and  P ‾ ⊤ 1 M + 1 ≤ b (10) \overline{\mathbf{P}} \mathbf{1}_{N+1} \leq \mathbf{a} \quad \text { and } \quad \overline{\mathbf{P}}^{\top} \mathbf{1}_{M+1}\leq\mathbf{b}\tag{10} P1N+1a and P1M+1b(10)
考虑极端情况,若两幅图只有一对点是匹配上的,也就是N+1个dustbin的数值中有N个是为1, M+1个dustbin的值有M个为1,匹配上那个点的dustbin为0,则有 a = [ 1 M ⊤ N ] ⊤ , b = [ 1 N ⊤ M ] ⊤ \mathbf{a}=\left[\begin{array}{ll} \mathbf{1}_{M}^{\top} & N \end{array}\right]^{\top}, \mathbf{b}=\left[\begin{array}{ll} \mathbf{1}_{N}^{\top} & M \end{array}\right]^{\top} a=[1MN],b=[1NM]

Sinkhorn Algorithm

最后由Sinkhorn Algorithm算法来接上述的优化问题,得到最终的分配矩阵;


损失函数

  SuperGlue的过程都是可微的,可以使用梯度下降法来进行优化,损失函数如式10所示:
 Loss  = − ∑ ( i , j ) ∈ M log ⁡ P ‾ i , j − ∑ i ∈ I log ⁡ P ‾ i , N + 1 − ∑ j ∈ J log ⁡ P ‾ M + 1 , j (10) \begin{aligned} \text { Loss }=&-\sum_{(i, j) \in \mathcal{M}} \log \overline{\mathbf{P}}_{i, j} -\sum_{i \in \mathcal{I}} \log \overline{\mathbf{P}}_{i, N+1}-\sum_{j \in \mathcal{J}} \log \overline{\mathbf{P}}_{M+1, j} \end{aligned}\tag{10}  Loss =(i,j)MlogPi,jiIlogPi,N+1jJlogPM+1,j(10)
其中 M = { ( i , j ) } \mathcal{M}=\{(i, j)\} M={(i,j)} 为两幅图像的Ground True,对于没有匹配的点 I ⊆ A 与 J ⊆ B \mathcal{I} \subseteq \mathcal{A} 与 \mathcal{J} \subseteq \mathcal{B} IAJB,将其dustbin维度设为1作为Ground True;


实验结果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

### Superglue 权重文件下载与参数配置 #### 权重文件的获取 为了使用 Superglue 模型,通常需要先从官方或其他可信资源处下载预训练权重文件。这些权重通常是 `.pth` 格式的 PyTorch 模型文件[^1]。如果目标是在 C++ 中通过 libtorch 使用该模型,则需将 `.pth` 文件转换为 `.bin` 或其他兼容格式,并保存为适合 libtorch 的 `.pt` 文件。 以下是具体操作流程: 1. **下载官方权重** 官方发布的 Superglue 和 Superpoint 模型权重可以从其 GitHub 仓库或相关论文页面找到并下载。例如,在 Superglue 的官方实现中,提供了多个版本的预训练权重(如室内场景、室外场景等)。可以通过链接直接下载对应的 `.pth` 文件[^3]。 2. **转换权重格式** 将下载好的 `.pth` 文件转换为 libtorch 可用的 `.pt` 文件。可以借助 Python 脚本完成此过程: ```cpp torch::save(model, "libtorch_superglue.pt"); ``` #### 参数配置说明 Superglue 模型的初始化涉及一系列重要参数,主要包括但不限于以下几项: - `keypoint_threshold`: 关键点检测的概率阈值。 - `nms_radius`: 非极大值抑制 (Non-Maximum Suppression) 半径。 - `weights`: Superglue 模型使用的权重名称(如 indoor、outdoor 等)。 - `sinkhorn_iterations`: Sinkhorn 迭代次数,默认为 20。 - `match_threshold`: 匹配概率阈值,低于此值的匹配会被忽略。 在实际应用中,可以根据需求调整上述参数以优化性能。例如,对于高精度的应用场景,可能需要降低 `keypoint_threshold` 并增加 `nms_radius`。 #### 示例代码片段 以下是一个简单的 C++ 实现示例,展示如何加载 Superglue 模型及其权重文件: ```cpp #include <torch/torch.h> #include <iostream> int main() { try { // 加载已保存的 Superglue 模型 torch::jit::script::Module model; model = torch::jit::load("libtorch_superglue.pt"); // 移动到 GPU 设备 model.to(torch::kCUDA); // 设置评估模式 model.eval(); std::cout << "Model loaded successfully." << std::endl; // 假设输入数据已经准备好 auto input_tensor = torch::rand({1, 3, 224, 224}).cuda(); auto output = model.forward({input_tensor}); std::cout << "Output shape: " << output.toTensor().sizes() << std::endl; } catch (const c10::Error& e) { std::cerr << "Error loading the model: " << e.what() << std::endl; } } ``` #### 注意事项 - 如果硬件不支持 CUDA,可以在 CPU 上运行推理,但速度会显著下降[^2]。 - 在虚拟环境中测试时,可通过命令行脚本验证模型功能,例如: ```bash python demo_superglue.py --input assets/scannet_sample_images/ --output_dir output/ --resize -1 -1 --force_cpu ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CV科研随想录

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

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

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

打赏作者

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

抵扣说明:

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

余额充值