1. 前言
detect-then-describe:对应 sparse local features,首先通过检测器得到特征点,然后提取特征点周围的 patch 得到描述符。
缺点:差异大的图像对效果不好(昼夜、季节、弱纹理场景)
原因:描述符由较大的区域得到,而特征点由很小区域的低级信息得到(角点等),导致检测的结果不稳定。
作者表示,即使对应的特征点检测不到,但是描述符仍然可以成功匹配,所以放弃检测阶段,而是密集提取描述符,代价是匹配时间和内存消耗。
detect-and-describe:本文的方法,通过 CNN 得到特征图,然后同时计算描述符并检测特征点。检测的特征点应当是在局部有不同的描述符的像素,这样会更适合匹配。
缺点:(1)由于密集提取描述符,效率低,计算量大;(2)检测基于高级信息虽然鲁棒性好但是准确度低,但是也足够用于视觉定位和 SfM
2. 方法
2.1 特征提取
首先是常规的用 CNN 提取图像 I I I 的特征 F = F ( I ) , F ∈ R h × w × n F = \mathcal{F} (I), F\in\mathbb{R} ^{h\times w\times n} F=F(I),F∈Rh×w×n,论文中给了特征两种写法:
(1) d i j = F i j : , d ∈ R n \mathbf{d}_{i j}=F_{i j:},\ \mathbf{d} \in \mathbb{R}^{n} dij=Fij:, d∈Rn 某个像素 i j ij ij 的特征向量
(2) D k = F : : k , D k ∈ R h × w D^{k}=F_{:: k},\ D^{k} \in \mathbb{R}^{h \times w} Dk=F::k, Dk∈Rh×w 某个维度 k k k 的特征图
这里将特征提取函数 F \mathcal{F} F 理解为 n n n 个不同的特征检测函数 D k \mathcal{D}^k Dk,每个检测函数输出一个二维特征图 D k D^{k} Dk。
2.2 特征点检测
定义特征点 ( i , j ) (i,j) (i,j):
( i , j ) is a detection * D i j k is a local max. in D k with k = arg max t D i j t \begin{array}{ll} (i, j) \text{ is a detection} \Longleftrightarrow & D_{i j}^{k} \text{ is a local max. in } D^{k} \\ &\text {with } k=\underset{t}{\arg \max } D_{i j}^{t} \end{array} (i,j) is a detection*Dijk is a local max. in Dkwith k=targmaxDijt
即两个条件,像素点 ( i , j ) (i,j) (i,j) 的特征向量中最大值索引为 k k k,且这个最大特征值在 D k D^{k} Dk 的局部区域也是最大值。
为了在训练过程中便于反向传播,定义局部最大值得分,其中 N ( i , j ) \mathcal{N}(i, j) N(i,j) 是以 ( i , j ) (i,j) (i,j) 为中心的 3 × 3 3\times3 3×3 区域:
α i j k = exp ( D i j k ) ∑ ( i ′ , j ′ ) ∈ N ( i , j ) exp ( D i ′ j ′ k ) \alpha_{i j}^{k}=\frac{\exp \left(D_{i j}^{k}\right)}{\sum_{\left(i^{\prime}, j^{\prime}\right) \in \mathcal{N}(i, j)} \exp \left(D_{i^{\prime} j^{\prime}}^{k}\right)} αijk=∑(i′,j′)∈N(i,j)exp(Di′j′k)exp(Dijk)
通道选择得分:
β i j k = D i j k / max t D i j t \beta_{i j}^{k}=D_{i j}^{k} / \max _{t} D_{i j}^{t} βijk=Dijk/tmaxDijt
Next, in order to take both criteria into account, we maximize the product of both scores across all feature maps k k k to obtain a single score map:
同时考虑两个得分标准,在所有特征图上最大化两个得分的乘积,得到一个一维的特征图(2021.12.9 可能是翻译的不对,后来看这句话有点迷惑,个人理解就是每个像素有个特征向量,特征向量的每个通道对应上面的操作计算出各自的得分;得分最高的作为整个特征向量也就是这个像素的得分,从而构成得分图):
γ i j = max k ( α i j k β i j k ) \gamma_{i j}=\max _{k}\left(\alpha_{i j}^{k} \beta_{i j}^{k}\right) γij=kmax(αijkβijk)
最后通过归一化得到每个像素的检测得分:
s i j = γ i j / ∑ ( i ′ , j ′ ) γ i ′ j ′ s_{i j}=\gamma_{i j} / \sum_{\left(i^{\prime}, j^{\prime}\right)} \gamma_{i^{\prime} j^{\prime}} sij=γij/(i′,j′)∑γi′j′
2.3 损失函数
给定一对图像 ( I 1 , I 2 ) (I_1,I_2) (I1,I2) 和它们的匹配关系 c : A B c:A\leftrightarrow B c:AB,损失函数的目的是最小化相匹配的描述符 d ^ A ( 1 ) \hat{\mathbf{d}}_{A}^{(1)} d^A(1) 和 d ^ B ( 2 ) \hat{\mathbf{d}}_{B}^{(2)} d^B(2) 的距离 p ( c ) p(c) p(c),同时最大化与其不匹配的描述符 d ^ N 1 ( 1 ) \hat{\mathbf{d}}_{N_1}^{(1)} d^N1(1) 和 d ^ N 2 ( 2 ) \hat{\mathbf{d}}_{N_2}^{(2)} d^N2(2) 的距离 n ( c ) n(c) n(c)。整个损失是在 triplet margin ranking loss 的基础上修改的。
p ( c ) = ∥ d ^ A ( 1 ) − d ^ B ( 2 ) ∥ 2 n ( c ) = min ( ∥ d ^ A ( 1 ) − d ^ N 2 ( 2 ) ∥ 2 , ∥ d ^ N 1 ( 1 ) − d ^ B ( 2 ) ∥ 2 ) p(c)=\left\|\hat{\mathbf{d}}_{A}^{(1)}-\hat{\mathbf{d}}_{B}^{(2)}\right\|_{2} \\ \ \\ n(c)=\min \left(\left\|\hat{\mathbf{d}}_{A}^{(1)}-\hat{\mathbf{d}}_{N_{2}}^{(2)}\right\|_{2},\left\|\hat{\mathbf{d}}_{N_{1}}^{(1)}-\hat{\mathbf{d}}_{B}^{(2)}\right\|_{2}\right) p(c)=∥∥∥d^A(1)−d^B(2)∥∥∥2 n(c)=min(∥∥∥d^A(1)−d^N2(2)∥∥∥2,∥∥∥d^N1(1)−d^B(2)∥∥∥2)
不匹配的负样本是选择匹配像素周围一定区域以外,且与该描述符距离最小的样本
N 1 = arg min P ∈ I 1 ∥ d ^ P ( 1 ) − d ^ B ( 2 ) ∥ 2 s.t. ∥ P − A ∥ ∞ > K N_{1}=\underset{P \in I_{1}}{\arg \min }\left\|\hat{\mathbf{d}}_{P}^{(1)}-\hat{\mathbf{d}}_{B}^{(2)}\right\|_{2} \text { s.t. }\|P-A\|_{\infty}>K N1=P∈I1argmin∥∥∥d^P(1)−d^B(2)∥∥∥2 s.t. ∥P−A∥∞>K
给定边界条件 M M M,损失定义为:
m ( c ) = max ( 0 , M + p ( c ) 2 − n ( c ) 2 ) m(c)=\max \left(0, M+p(c)^{2}-n(c)^{2}\right) m(c)=max(0,M+p(c)2−n(c)2)
此时,损失 m ( c ) m(c) m(c) 会抑制任意可能导致错误匹配的特征对,从而加强描述符的独特性。为了检测的可重复性,在损失中加入一个检测项,作为最终的损失:
L ( I 1 , I 2 ) = ∑ c ∈ C s c ( 1 ) s c ( 2 ) ∑ q ∈ C s q ( 1 ) s q ( 2 ) m ( p ( c ) , n ( c ) ) \mathcal{L}\left(I_{1}, I_{2}\right)=\sum_{c \in \mathcal{C}} \frac{s_{c}^{(1)} s_{c}^{(2)}}{\sum_{q \in \mathcal{C}} s_{q}^{(1)} s_{q}^{(2)}} m(p(c), n(c)) L(I1,I2)=c∈C∑∑q∈Csq(1)sq(2)sc(1)sc(2)m(p(c),n(c))
其中 s c ( 1 ) s c ( 2 ) s_{c}^{(1)} s_{c}^{(2)} sc(1)sc(2) 是检测得分, C \mathcal{C} C 是所有匹配点的集合。
把左半部分作为检测项,右半部分作为特征项,从各个公式可以发现,检测项越大,是特征点的概率越高,特征项越小,特征越准确(或者说越容易得到正确的匹配);这样一来当最小化损失时,越可能是特征点的部分他的特征就越准确,而不太可能是特征点的位置,特征不准确也影响不大。
3. 细节
原始数据集是 MegaDepth,选出稀疏 SfM 点云重叠高于50%的作为图像对。每一对图像,通过深度信息将第二张图像的所有点投影到第一张图像中,并通过核查深度图去除遮挡的像素。
训练的时候对每一对图像随机裁剪出一个以一个对应关系为中心的 256 × 256 256\times 256 256×256 的区域,训练的 batch size 取1,并确保有至少128个对应关系。
测试的时候修改了一些网络结构,让输出的特征图分辨率提高(输入图像的四分之一),从而得到更多的特征点,点的位置也会更准。
4. 个人总结
D2-Net 所用的训练数据是利用深度信息获取像素级对应关系的图像对,这样便有足够的标签让网络的特征正确匹配。之后的问题就在于如何确定特征点的位置,这边的解决方案就是(参考传统算法)设计一套规则,在特征图上进行运算得到像素级的得分图。
文章评论