中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

有幾個網(wǎng)站能在百度做推廣怎么弄推廣廣告

有幾個網(wǎng)站能在百度做推廣,怎么弄推廣廣告,大學生可以做的網(wǎng)站項目,申請?zhí)柕木W(wǎng)站目錄 摘要Abstract一、文獻閱讀1.1 摘要1.2 背景1.3 論文方法1.3.1 局部特征提取1.3.2 局部特征轉(zhuǎn)換器 (LoFTR) 模塊1.3.4 建立粗粒度匹配1.3.5 精細匹配 1.4 損失1.5 實現(xiàn)細節(jié)1.6 實驗1.6.1 單應(yīng)性估計1.6.2 相對位姿估計 二、論文代碼總結(jié) 摘要 本周閱讀了一篇特征匹配領(lǐng)域的…

目錄

  • 摘要
  • Abstract
  • 一、文獻閱讀
    • 1.1 摘要
    • 1.2 背景
    • 1.3 論文方法
      • 1.3.1 局部特征提取
      • 1.3.2 局部特征轉(zhuǎn)換器 (LoFTR) 模塊
      • 1.3.4 建立粗粒度匹配
      • 1.3.5 精細匹配
    • 1.4 損失
    • 1.5 實現(xiàn)細節(jié)
    • 1.6 實驗
      • 1.6.1 單應(yīng)性估計
      • 1.6.2 相對位姿估計
  • 二、論文代碼
  • 總結(jié)

摘要

本周閱讀了一篇特征匹配領(lǐng)域的論文。LoFTR,一種創(chuàng)新的局部圖像特征匹配方法,為3D計算機視覺領(lǐng)域帶來革命性突破。它摒棄了傳統(tǒng)特征檢測、描述和匹配的繁瑣步驟,通過像素級的粗粒度密集匹配,優(yōu)化了良好匹配的效果。該方法利用Transformer中的自注意力和交叉注意力層,獲取全局感受野,解決了低紋理區(qū)域匹配難題,性能優(yōu)于最先進方法。在復雜的室內(nèi)和室外環(huán)境中,LoFTR展現(xiàn)出強大的匹配能力,特別是在處理重復紋理和模式時,其優(yōu)勢更為顯著。相比基于檢測器的SuperGlue方法,LoFTR克服了檢測器在尋找對應(yīng)關(guān)系時的局限性,實現(xiàn)了更全面的特征提取和匹配。LoFTR的成功不僅在于其創(chuàng)新的設(shè)計,更在于其深入理解了圖像匹配的本質(zhì)。它借鑒了人類視覺系統(tǒng)的特點,能夠結(jié)合局部和全局信息進行匹配,從而提高了對應(yīng)點的準確性。這一特點使得LoFTR在應(yīng)對復雜環(huán)境中的匹配難題時,能夠展現(xiàn)出更強大的能力。此外,LoFTR還通過采用線性Transformer等優(yōu)化手段,降低了計算復雜度,提高了實際應(yīng)用價值。這一優(yōu)勢使得LoFTR在保持高性能的同時,也能夠滿足實時性要求較高的應(yīng)用場景。

Abstract

This week, I read a paper on feature matching in the field. LoFTR, an innovative local image feature matching method, has brought revolutionary breakthroughs to the 3D computer vision field. It abandons the cumbersome steps of traditional feature detection, description, and matching, and optimizes the effect of good matches through pixel-level coarse-grained dense matching. This method utilizes self-attention and cross-attention layers in Transformer to obtain global receptive fields, addressing the challenge of matching in low-texture areas and outperforming state-of-the-art methods.In complex indoor and outdoor environments, LoFTR demonstrates strong matching capabilities, especially when dealing with repetitive textures and patterns. Compared to the detector-based SuperGlue method, LoFTR overcomes the limitations of detectors in finding correspondences, achieving more comprehensive feature extraction and matching.The success of LoFTR lies not only in its innovative design but also in its deep understanding of the essence of image matching. It draws inspiration from the characteristics of the human visual system, able to combine local and global information for matching, thereby improving the accuracy of corresponding points. This characteristic enables LoFTR to demonstrate greater capabilities when dealing with matching challenges in complex environments.
Furthermore, LoFTR reduces computational complexity and enhances practical application value by adopting optimization techniques such as linear Transformer. This advantage allows LoFTR to maintain high performance while meeting the real-time requirements of demanding applications.

一、文獻閱讀

題目:LoFTR: Detector-Free Local Feature Matching with Transformers

1.1 摘要

我們提出了一種局部圖像特征匹配的新方法。 我們建議首先在粗略水平上建立像素級密集匹配,然后在精細水平上細化良好的匹配,而不是依次執(zhí)行圖像特征檢測、描述和匹配。 與使用成本量來搜索對應(yīng)關(guān)系的密集方法相比,我們在 Transformer 中使用自注意力層和交叉注意力層來獲取以兩張圖像為條件的特征描述符。 Transformer 提供的全局感受野使我們的方法能夠在低紋理區(qū)域產(chǎn)生密集匹配,而特征檢測器通常很難在這些區(qū)域產(chǎn)生可重復的興趣點。 室內(nèi)和室外數(shù)據(jù)集的實驗表明,LoFTR 的性能大幅優(yōu)于最先進的方法。

1.2 背景

大多數(shù)現(xiàn)有的匹配方法由三個獨立的部分組成 階段:特征檢測、特征描述和特征匹配。

  • 特征檢測:從圖像中提取顯著且可重復的興趣點,例如角點、邊緣等。
  • 特征描述:為每個檢測到的興趣點生成一個獨特的描述子,以便在后續(xù)步驟中與其他圖像的特征進行比較。
  • 特征匹配:通過比較描述子,找到兩幅圖像之間的對應(yīng)特征點。

特征檢測器的使用減少了匹配的搜索空間。 然而,由于各種因素,例如不良紋理、重復圖案、視點變化、照明變化和運動模糊等,特征檢測器可能無法提取足夠多的圖像之間可重復的興趣點。 這個問題在室內(nèi)環(huán)境中尤其突出,低紋理區(qū)域或重復圖案有時占據(jù)視野中的大部分區(qū)域。 圖 1 顯示了一個示例。 如果沒有可重復的興趣點,即使有完美的描述符也無法找到正確的對應(yīng)關(guān)系。
在這里插入圖片描述
最近的幾項工作試圖通過建立像素密集匹配來解決這個問題。 可以從密集匹配中選擇具有高置信度分數(shù)的匹配,從而避免特征檢測。 然而,這些作品中卷積神經(jīng)網(wǎng)絡(luò)(CNN)提取的密集特征的感受野有限,可能無法區(qū)分不明顯的區(qū)域。 相反,人類在這些不明顯的區(qū)域中不僅基于當?shù)厣鐓^(qū),而且還基于更大的全球背景來尋找對應(yīng)關(guān)系。 例如,圖1中的低紋理區(qū)域可以根據(jù)它們與邊緣的相對位置來區(qū)分。 這一觀察結(jié)果告訴我們,特征提取網(wǎng)絡(luò)中較大的感受野至關(guān)重要。

1.3 論文方法

給定圖像對 IA 和 IB,現(xiàn)有的局部特征匹配方法使用特征檢測器來提取興趣點。 我們建議通過無檢測器設(shè)計來解決特征檢測器的可重復性問題。 圖 2 概述了所提出的 LoFTR 方法。
在這里插入圖片描述

1.3.1 局部特征提取

我們使用帶有 FPN [22](表示為局部特征 CNN)的標準卷積架構(gòu)從兩個圖像中提取多級特征。 我們使用 ~FA 和 ~FB表示原始圖像維度1/8處的粗級特征,并且 ^FA 和 ^FB表示原始圖像維度1/2處的精細級特征。 卷積神經(jīng)網(wǎng)絡(luò)(CNN)具有平移等方差和局部性的歸納偏差,非常適合局部特征提取。 CNN 引入的下采樣還減少了 LoFTR 模塊的輸入長度,這對于確保可管理的計算成本至關(guān)重要。
在這里插入圖片描述

1.3.2 局部特征轉(zhuǎn)換器 (LoFTR) 模塊

在局部特征提取之后, ~FA 和 ~FB通過LoFTR模塊來提取位置和上下文相關(guān)的局部特征。 直觀上,LoFTR 模塊將特征轉(zhuǎn)換為易于匹配的特征表示。 我們將變換后的特征表示為 F ~A tr 和 ~FB tr。
在這里插入圖片描述 Transformer 編碼器由順序連接的編碼器層組成。 圖3(a)顯示了編碼器層的架構(gòu)。 編碼器層的關(guān)鍵元素是注意力層。 注意力層的輸入向量通常稱為查詢、鍵和值。 與信息檢索類似,查詢向量 Q 根據(jù) Q 和每個值 V 對應(yīng)的關(guān)鍵向量 K 的點積計算出的注意力權(quán)重,從值向量 V 中檢索信息。注意力層的計算圖如下所示 圖3(b)。 形式上,注意力層表示為:
在這里插入圖片描述
在這里插入圖片描述
位置編碼: 我們按照 DETR 在 Transformers 中使用標準位置編碼的 2D 擴展。 與 DETR 不同,我們只將它們添加到骨干輸出一次。 我們將位置編碼的正式定義留在補充材料中。 直觀上,位置編碼以正弦格式為每個元素提供唯一的位置信息。 通過將位置編碼添加到 F~A 和 F~B,變換后的特征將變得位置相關(guān),這對于 LoFTR 在不明顯的區(qū)域中產(chǎn)生匹配的能力至關(guān)重要。 如圖 4? 的底行所示,雖然輸入 RGB 顏色在白墻上是均勻的,但平滑顏色梯度所展示的每個位置的變換特征 F~ A tr 和 F~ B tr 都是唯一的。 圖 6 提供了更多可視化效果。
在這里插入圖片描述
自注意力和交叉注意力層: 對于自注意力層,輸入特征 fi 和 fj (如圖 3 所示)是相同的(?FA 或?FB)。 對于交叉注意力層,輸入特征 fi 和 fj 要么是( FA 和 F B),要么是(FB 和 F A),具體取決于交叉注意力的方向。 遵循[37],我們將 LoFTR 模塊中的自注意力層和交叉注意力層交錯 Nc 次。 LoFTR 中自注意力層和交叉注意力層的注意力權(quán)重在圖 4? 的前兩行中可視化。
將粗略特征圖輸入至粗特征提取的transformer提取匹配特征,該transformer由多個交替的自注意力和交叉注意力層構(gòu)成,自注意力層使得每個點關(guān)注其周圍所有點的關(guān)聯(lián),交叉注意力層使得點關(guān)注與另一幅圖上的所有點的關(guān)聯(lián)

1.3.4 建立粗粒度匹配

使用乘積的方式先計算所有位置的匹配得分矩陣 S,然后計算最優(yōu)匹配,可以通過最優(yōu)傳輸OT算法或者dual-softmax方法,文中使用的是dual-softmax, 然后再通過互近鄰MNN算法過濾掉一些離群匹配對。
匹配概率Pc由下式獲得:
在這里插入圖片描述

1.3.5 精細匹配

通過粗匹配得到粗粒度的匹配結(jié)果,例如匹配點對(i1,j1),(i2,j2), 將其映射到對應(yīng)的精細特征圖,并且將其(w,w)領(lǐng)域裁剪出來(相當于裁剪出來了w*w個位置的特征),輸入至精細特征提取的transformer提取匹配特征,得到FA和FB,然后計算FA中心特征與FB中所有特征的匹配概率(即相似度),再計算該概率分布即可計算出FB中的亞像素精度的匹配點位置(應(yīng)該是通過領(lǐng)域(5,5)以及對應(yīng)的概率,加權(quán)相加計算出精細位置,是亞像素級別的)

1.4 損失

最終的coarse-to-fine上的代價由如下組成:
在這里插入圖片描述
粗粒度代價:通過在置信矩陣Pc上使用負對數(shù)似然得到最終的代價,兩個網(wǎng)格之間的距離是由其中心位置的重投影距離來衡量的。在使用雙軟性匹配時,我們將Mgt中網(wǎng)格的負對數(shù)可能性損失降到最低。
在這里插入圖片描述
細粒度代價:我們使用?2損失來進行精細的精細化。按照,對于每個查詢點i,我們也通過計算總方差σ2(?i)來衡量其不確定性。我們的目標是要優(yōu)化具有低不確定性的精煉位置,結(jié)果是形成最終的加權(quán)損失函數(shù)。
在這里插入圖片描述

1.5 實現(xiàn)細節(jié)

我們在ScanNet數(shù)據(jù)集上訓練了LoFTR的室內(nèi)模型,并在MegaDepth上訓練了室外模型,按照的方法進行。在ScanNet上,模型使用Adam進行訓練,初始學習率為1×10?3,批次大小為64。經(jīng)過64張GTX1080Ti GPU的24小時訓練后模型收斂。局部特征CNN使用修改版的ResNet-18 [12]作為骨干網(wǎng)絡(luò)。整個模型的權(quán)重是隨機初始化的并進行端到端的訓練。Nc設(shè)置為4,Nf設(shè)置為1,θc選擇0.2。窗口大小w等于5。在實現(xiàn)中,將F?Atr和F?Btr上采樣并與F?A和F?B進行拼接,然后通過細匹配級別的LoFTR。使用雙向softmax匹配的完整模型在一對640×480的圖像上運行時間為116毫秒,使用RTX 2080Ti。在最優(yōu)傳輸設(shè)置下,我們使用三個Sinkhorn迭代,模型運行時間為130毫秒。更多訓練和計時分析的細節(jié)請參見補充材料。

1.6 實驗

1.6.1 單應(yīng)性估計

評估協(xié)議:在每個測試序列中,將一個參考圖像與其他五個圖像配對。所有圖像的尺寸調(diào)整為較短邊等于480像素。對于每對圖像,我們使用在MegaDepth數(shù)據(jù)集上訓練的LoFTR提取一組匹配點。我們使用OpenCV計算采用RANSAC作為魯棒估計器的單應(yīng)性矩陣估計。為了與產(chǎn)生不同數(shù)量匹配點的方法進行公平比較,我們使用角點誤差來衡量通過估計的H?對圖像進行變換后與真實H之間的差異,與中的正確性指標一致。按照的做法,我們分別報告了3、5和10像素閾值下角點誤差累積曲線下面積(AUC)。我們報告LoFTR輸出最多1K匹配點時的結(jié)果。

基準方法:我們將LoFTR與三類方法進行比較:1)基于檢測器的局部特征方法,包括R2D2、D2Net和DISK;2)基于檢測器的局部特征匹配方法,即SuperGlue在SuperPoint特征上的擴展;3)無需檢測器的匹配方法,包括Sparse-NCNet和DRC-Net。對于局部特征方法,我們最多提取2K個特征,并提取相互最近鄰作為最終匹配點。對于直接輸出匹配點的方法,我們限制最多1K個匹配點,與LoFTR一樣。對于所有基準方法,我們使用原始實現(xiàn)中的默認超參數(shù)。

結(jié)果。表1顯示,LoFTR在所有誤差閾值下明顯優(yōu)于其他基準方法。具體而言,隨著正確性閾值越來越嚴格,LoFTR與其他方法之間的性能差距增大。我們將頂級性能歸因于無需檢測器的設(shè)計提供的更多匹配候選項以及Transformer帶來的全局感受野。此外,粗到精模塊通過將匹配點細化到亞像素級別也有助于估計的準確性。
在這里插入圖片描述

1.6.2 相對位姿估計

數(shù)據(jù)集:我們使用ScanNet和MegaDepth數(shù)據(jù)集分別展示LoFTR在室內(nèi)和室外場景中進行位姿估計的效果。

ScanNet包含1613個帶有地面真實位姿和深度圖的單目序列。按照SuperGlue的步驟,我們對訓練集采樣了230M對圖像,其重疊得分在0.4到0.8之間。我們在中的1500個測試圖像對上評估我們的方法。所有圖像和深度圖的尺寸調(diào)整為640×480像素。該數(shù)據(jù)集包含了基線較大和紋理缺失區(qū)域較多的圖像對。

MegaDepth由196個不同室外場景的100萬張互聯(lián)網(wǎng)圖像組成。作者還提供了使用COLMAP進行稀疏重建和使用多視圖立體法計算深度圖的數(shù)據(jù)。我們按照DISK的方法,只使用"Sacre Coeur"和"St. Peter’s Square"兩個場景進行驗證,并從中采樣了1500對圖像用于公平比較。訓練時,圖像的較長邊被調(diào)整為840像素,驗證時調(diào)整為1200像素。MegaDepth的關(guān)鍵挑戰(zhàn)是在極端視點變化和重復紋理的情況下進行匹配。

評估協(xié)議:按照的做法,我們報告在閾值為5°、10°和20°時的位姿誤差的AUC,其中位姿誤差定義為旋轉(zhuǎn)和平移中角度誤差的最大值。為了恢復相機位姿,我們使用RANSAC從預測的匹配點中求解本質(zhì)矩陣。由于無需檢測器的圖像匹配方法缺乏定義明確的度量(如匹配得分或召回率),我們不對LoFTR和其他基于檢測器的方法進行匹配精度比較。我們將DRC-Net視為無需檢測器方法中的最先進方法。
在這里插入圖片描述

二、論文代碼

基礎(chǔ)特征提取模塊Local Feature CNN
通過CNN提取特征圖

# 1. Local Feature CNNdata.update({'bs': data['image0'].size(0),'hw0_i': data['image0'].shape[2:], 'hw1_i': data['image1'].shape[2:]})if data['hw0_i'] == data['hw1_i']:  # faster & better BN convergenceprint(torch.cat([data['image0'], data['image1']], dim=0).shape)feats_c, feats_f = self.backbone(torch.cat([data['image0'], data['image1']], dim=0))print(feats_c.shape) # 1/8print(feats_f.shape) # 1/2(feat_c0, feat_c1), (feat_f0, feat_f1) = feats_c.split(data['bs']), feats_f.split(data['bs'])print(feat_c0.shape)print(feat_c1.shape)print(feat_f0.shape)print(feat_f1.shape)else:  # handle different input shapes(feat_c0, feat_f0), (feat_c1, feat_f1) = self.backbone(data['image0']), self.backbone(data['image1'])print(feat_c0.shape)print(feat_c1.shape)print(feat_f0.shape)print(feat_f1.shape)data.update({'hw0_c': feat_c0.shape[2:], 'hw1_c': feat_c1.shape[2:],'hw0_f': feat_f0.shape[2:], 'hw1_f': feat_f1.shape[2:]})

這里的backbone就是一系列的卷積和連接操作,可以跳入self.backbone中去:

    def forward(self, x):# ResNet Backbonex0 = self.relu(self.bn1(self.conv1(x)))x1 = self.layer1(x0)  # 1/2x2 = self.layer2(x1)  # 1/4x3 = self.layer3(x2)  # 1/8# FPNx3_out = self.layer3_outconv(x3)x3_out_2x = F.interpolate(x3_out, scale_factor=2., mode='bilinear', align_corners=True)x2_out = self.layer2_outconv(x2)x2_out = self.layer2_outconv2(x2_out+x3_out_2x)x2_out_2x = F.interpolate(x2_out, scale_factor=2., mode='bilinear', align_corners=True)x1_out = self.layer1_outconv(x1)x1_out = self.layer1_outconv2(x1_out+x2_out_2x)return [x3_out, x1_out]

注意力機制應(yīng)用 coarse-level loftr module

        # 2. coarse-level loftr module# add featmap with positional encoding, then flatten it to sequence [N, HW, C]# 添加位置編碼feat_c0 = rearrange(self.pos_encoding(feat_c0), 'n c h w -> n (h w) c')print(feat_c0.shape)feat_c1 = rearrange(self.pos_encoding(feat_c1), 'n c h w -> n (h w) c')print(feat_c1.shape)mask_c0 = mask_c1 = None  # mask is useful in trainingif 'mask0' in data:mask_c0, mask_c1 = data['mask0'].flatten(-2), data['mask1'].flatten(-2)# 進入transformer模塊,這是論文的核心模塊feat_c0, feat_c1 = self.loftr_coarse(feat_c0, feat_c1, mask_c0, mask_c1)print(feat_c0.shape)print(feat_c1.shape)

進入self.loftr_coarse模塊,這里需要計算自身的attention注意力,還需要將兩張圖像計算cross attention,從代碼中的循環(huán)中可以看到,self和cross兩種操作分別是自己和自己計算注意力以及自己和其他特征圖計算注意力,從layer的計算參數(shù)可以明確這一點。

    def forward(self, feat0, feat1, mask0=None, mask1=None):"""Args:feat0 (torch.Tensor): [N, L, C]feat1 (torch.Tensor): [N, S, C]mask0 (torch.Tensor): [N, L] (optional)mask1 (torch.Tensor): [N, S] (optional)"""assert self.d_model == feat0.size(2), "the feature number of src and transformer must be equal"for layer, name in zip(self.layers, self.layer_names):if name == 'self':feat0 = layer(feat0, feat0, mask0, mask0)print(feat0.shape)feat1 = layer(feat1, feat1, mask1, mask1)print(feat1.shape)elif name == 'cross':feat0 = layer(feat0, feat1, mask0, mask1)print(feat0.shape)feat1 = layer(feat1, feat0, mask1, mask0)print(feat1.shape)else:raise KeyErrorprint(feat0.shape)print(feat1.shape)return feat0, feat1

具體的計算layer在LoFTREncoderLayer定義中,這里就是基本的attention計算方法,主要是QKV的計算和一些線性計算、連接操作。

    def forward(self, x, source, x_mask=None, source_mask=None):"""Args:x (torch.Tensor): [N, L, C]source (torch.Tensor): [N, S, C]x_mask (torch.Tensor): [N, L] (optional)source_mask (torch.Tensor): [N, S] (optional)"""bs = x.size(0)query, key, value = x, source, source# multi-head attentionquery = self.q_proj(query).view(bs, -1, self.nhead, self.dim)  # [N, L, (H, D)]key = self.k_proj(key).view(bs, -1, self.nhead, self.dim)  # [N, S, (H, D)]value = self.v_proj(value).view(bs, -1, self.nhead, self.dim)message = self.attention(query, key, value, q_mask=x_mask, kv_mask=source_mask)  # [N, L, (H, D)]message = self.merge(message.view(bs, -1, self.nhead*self.dim))  # [N, L, C]message = self.norm1(message)# feed-forward networkmessage = self.mlp(torch.cat([x, message], dim=2))message = self.norm2(message)return x + message

粗粒度匹配模塊 match coarse-level

        # 3. match coarse-levelself.coarse_matching(feat_c0, feat_c1, data, mask_c0=mask_c0, mask_c1=mask_c1)

跟入coarse_matching模塊
通過注意力機制獲取到兩個圖像的特征圖,進入到粗粒度匹配模塊,粗粒度匹配是采用的內(nèi)積的計算方式,即下面代碼的torch.einsum計算,然后通過softmax轉(zhuǎn)成概率值。

    def forward(self, feat_c0, feat_c1, data, mask_c0=None, mask_c1=None):"""Args:feat0 (torch.Tensor): [N, L, C]feat1 (torch.Tensor): [N, S, C]data (dict)mask_c0 (torch.Tensor): [N, L] (optional)mask_c1 (torch.Tensor): [N, S] (optional)Update:data (dict): {'b_ids' (torch.Tensor): [M'],'i_ids' (torch.Tensor): [M'],'j_ids' (torch.Tensor): [M'],'gt_mask' (torch.Tensor): [M'],'mkpts0_c' (torch.Tensor): [M, 2],'mkpts1_c' (torch.Tensor): [M, 2],'mconf' (torch.Tensor): [M]}NOTE: M' != M during training."""N, L, S, C = feat_c0.size(0), feat_c0.size(1), feat_c1.size(1), feat_c0.size(2)# normalizefeat_c0, feat_c1 = map(lambda feat: feat / feat.shape[-1]**.5,[feat_c0, feat_c1])if self.match_type == 'dual_softmax':sim_matrix = torch.einsum("nlc,nsc->nls", feat_c0,feat_c1) / self.temperatureprint(sim_matrix.shape)if mask_c0 is not None:sim_matrix.masked_fill_(~(mask_c0[..., None] * mask_c1[:, None]).bool(),-INF)conf_matrix = F.softmax(sim_matrix, 1) * F.softmax(sim_matrix, 2)print(conf_matrix.shape)elif self.match_type == 'sinkhorn':# sinkhorn, dustbin includedsim_matrix = torch.einsum("nlc,nsc->nls", feat_c0, feat_c1)if mask_c0 is not None:sim_matrix[:, :L, :S].masked_fill_(~(mask_c0[..., None] * mask_c1[:, None]).bool(),-INF)# build uniform prior & use sinkhornlog_assign_matrix = self.log_optimal_transport(sim_matrix, self.bin_score, self.skh_iters)assign_matrix = log_assign_matrix.exp()conf_matrix = assign_matrix[:, :-1, :-1]# filter prediction with dustbin score (only in evaluation mode)if not self.training and self.skh_prefilter:filter0 = (assign_matrix.max(dim=2)[1] == S)[:, :-1]  # [N, L]filter1 = (assign_matrix.max(dim=1)[1] == L)[:, :-1]  # [N, S]conf_matrix[filter0[..., None].repeat(1, 1, S)] = 0conf_matrix[filter1[:, None].repeat(1, L, 1)] = 0if self.config['sparse_spvs']:data.update({'conf_matrix_with_bin': assign_matrix.clone()})data.update({'conf_matrix': conf_matrix})# predict coarse matches from conf_matrixdata.update(**self.get_coarse_match(conf_matrix, data))

跟入get_coarse_match模塊
通過softmax獲取到概率值之后,然后根據(jù)閾值使用mask矩陣過濾掉低于閾值的值,然后使用互最近鄰來確定互相匹配關(guān)系。

    def get_coarse_match(self, conf_matrix, data):"""Args:conf_matrix (torch.Tensor): [N, L, S]data (dict): with keys ['hw0_i', 'hw1_i', 'hw0_c', 'hw1_c']Returns:coarse_matches (dict): {'b_ids' (torch.Tensor): [M'],'i_ids' (torch.Tensor): [M'],'j_ids' (torch.Tensor): [M'],'gt_mask' (torch.Tensor): [M'],'m_bids' (torch.Tensor): [M],'mkpts0_c' (torch.Tensor): [M, 2],'mkpts1_c' (torch.Tensor): [M, 2],'mconf' (torch.Tensor): [M]}"""axes_lengths = {'h0c': data['hw0_c'][0],'w0c': data['hw0_c'][1],'h1c': data['hw1_c'][0],'w1c': data['hw1_c'][1]}_device = conf_matrix.device# 1. confidence thresholdingmask = conf_matrix > self.thrprint(mask.shape)mask = rearrange(mask, 'b (h0c w0c) (h1c w1c) -> b h0c w0c h1c w1c',**axes_lengths)print(mask.shape)if 'mask0' not in data:mask_border(mask, self.border_rm, False)else:mask_border_with_padding(mask, self.border_rm, False,data['mask0'], data['mask1'])mask = rearrange(mask, 'b h0c w0c h1c w1c -> b (h0c w0c) (h1c w1c)',**axes_lengths)print(mask.shape)# 2. mutual nearestprint(conf_matrix.max(dim=2, keepdim=True)[0].shape)mask = mask \* (conf_matrix == conf_matrix.max(dim=2, keepdim=True)[0]) \* (conf_matrix == conf_matrix.max(dim=1, keepdim=True)[0])print(mask.shape)# 3. find all valid coarse matches# this only works when at most one `True` in each rowmask_v, all_j_ids = mask.max(dim=2)print(mask_v.shape)print(all_j_ids.shape)b_ids, i_ids = torch.where(mask_v)print(b_ids.shape)print(i_ids.shape)j_ids = all_j_ids[b_ids, i_ids]print(j_ids.shape)mconf = conf_matrix[b_ids, i_ids, j_ids]print(mconf.shape)# 4. Random sampling of training samples for fine-level LoFTR# (optional) pad samples with gt coarse-level matchesif self.training:# NOTE:# The sampling is performed across all pairs in a batch without manually balancing# #samples for fine-level increases w.r.t. batch_sizeif 'mask0' not in data:num_candidates_max = mask.size(0) * max(mask.size(1), mask.size(2))else:num_candidates_max = compute_max_candidates(data['mask0'], data['mask1'])num_matches_train = int(num_candidates_max *self.train_coarse_percent)num_matches_pred = len(b_ids)assert self.train_pad_num_gt_min < num_matches_train, "min-num-gt-pad should be less than num-train-matches"# pred_indices is to select from predictionif num_matches_pred <= num_matches_train - self.train_pad_num_gt_min:pred_indices = torch.arange(num_matches_pred, device=_device)else:pred_indices = torch.randint(num_matches_pred,(num_matches_train - self.train_pad_num_gt_min, ),device=_device)# gt_pad_indices is to select from gt padding. e.g. max(3787-4800, 200)gt_pad_indices = torch.randint(len(data['spv_b_ids']),(max(num_matches_train - num_matches_pred,self.train_pad_num_gt_min), ),device=_device)mconf_gt = torch.zeros(len(data['spv_b_ids']), device=_device)  # set conf of gt paddings to all zerob_ids, i_ids, j_ids, mconf = map(lambda x, y: torch.cat([x[pred_indices], y[gt_pad_indices]],dim=0),*zip([b_ids, data['spv_b_ids']], [i_ids, data['spv_i_ids']],[j_ids, data['spv_j_ids']], [mconf, mconf_gt]))# These matches select patches that feed into fine-level networkcoarse_matches = {'b_ids': b_ids, 'i_ids': i_ids, 'j_ids': j_ids}# 4. Update with matches in original image resolutionscale = data['hw0_i'][0] / data['hw0_c'][0]scale0 = scale * data['scale0'][b_ids] if 'scale0' in data else scalescale1 = scale * data['scale1'][b_ids] if 'scale1' in data else scalemkpts0_c = torch.stack([i_ids % data['hw0_c'][1], i_ids // data['hw0_c'][1]],dim=1) * scale0mkpts1_c = torch.stack([j_ids % data['hw1_c'][1], j_ids // data['hw1_c'][1]],dim=1) * scale1# These matches is the current prediction (for visualization)coarse_matches.update({'gt_mask': mconf == 0,'m_bids': b_ids[mconf != 0],  # mconf == 0 => gt matches'mkpts0_c': mkpts0_c[mconf != 0],'mkpts1_c': mkpts1_c[mconf != 0],'mconf': mconf[mconf != 0]})return coarse_matches

精細化調(diào)整 fine-level refinement

        # 4. fine-level refinement# 預處理操作,拆解特征圖,提取匹配到的候選點feat_f0_unfold, feat_f1_unfold = self.fine_preprocess(feat_f0, feat_f1, feat_c0, feat_c1, data)if feat_f0_unfold.size(0) != 0:  # at least one coarse level predictedfeat_f0_unfold, feat_f1_unfold = self.loftr_fine(feat_f0_unfold, feat_f1_unfold)

細粒度匹配 match fine-level
跳入FineMatching的forward函數(shù)中
原文中使用55的矩陣進行細粒度匹配,這里匹配的時候會計算55矩陣中各個點與中間點的關(guān)系,生成熱度圖heatmap,然后計算這個熱度圖的期望dsnt.spatial_expectation2d,然后還原到圖像中即可。

    def forward(self, feat_f0, feat_f1, data):"""Args:feat0 (torch.Tensor): [M, WW, C]feat1 (torch.Tensor): [M, WW, C]data (dict)Update:data (dict):{'expec_f' (torch.Tensor): [M, 3],'mkpts0_f' (torch.Tensor): [M, 2],'mkpts1_f' (torch.Tensor): [M, 2]}"""M, WW, C = feat_f0.shapeW = int(math.sqrt(WW))scale = data['hw0_i'][0] / data['hw0_f'][0]self.M, self.W, self.WW, self.C, self.scale = M, W, WW, C, scale# corner case: if no coarse matches foundif M == 0:assert self.training == False, "M is always >0, when training, see coarse_matching.py"# logger.warning('No matches found in coarse-level.')data.update({'expec_f': torch.empty(0, 3, device=feat_f0.device),'mkpts0_f': data['mkpts0_c'],'mkpts1_f': data['mkpts1_c'],})returnfeat_f0_picked = feat_f0_picked = feat_f0[:, WW//2, :]print(feat_f0_picked.shape)sim_matrix = torch.einsum('mc,mrc->mr', feat_f0_picked, feat_f1)print(sim_matrix.shape)softmax_temp = 1. / C**.5heatmap = torch.softmax(softmax_temp * sim_matrix, dim=1).view(-1, W, W)print(heatmap.shape)# compute coordinates from heatmapcoords_normalized = dsnt.spatial_expectation2d(heatmap[None], True)[0]  # [M, 2]print(coords_normalized.shape)grid_normalized = create_meshgrid(W, W, True, heatmap.device).reshape(1, -1, 2)  # [1, WW, 2]print(grid_normalized.shape)# compute std over <x, y>var = torch.sum(grid_normalized**2 * heatmap.view(-1, WW, 1), dim=1) - coords_normalized**2  # [M, 2]std = torch.sum(torch.sqrt(torch.clamp(var, min=1e-10)), -1)  # [M]  clamp needed for numerical stability# for fine-level supervisiondata.update({'expec_f': torch.cat([coords_normalized, std.unsqueeze(1)], -1)})# compute absolute kpt coordsself.get_fine_match(coords_normalized, data)

總結(jié)

本周我閱讀了LoFTR方法,該方法為局部圖像特征匹配領(lǐng)域帶來了一種新穎的思路。傳統(tǒng)的圖像特征匹配流程通常包括特征檢測、特征描述和特征匹配三個獨立階段。然而,LoFTR打破了這一傳統(tǒng)框架,通過結(jié)合Transformer架構(gòu),直接在像素級別上建立粗匹配,并隨后在精細級別上優(yōu)化這些匹配。下一周我將開始EfficientLoFTR的學習。

http://www.risenshineclean.com/news/1792.html

相關(guān)文章:

  • 手機門戶網(wǎng)站百度推廣賬戶登錄首頁
  • 城鄉(xiāng)與建設(shè)部網(wǎng)站首頁seo工具不包括
  • 購物網(wǎng)站英語濟南做seo的公司排名
  • wordpress鏈接亞馬遜在線優(yōu)化工具
  • 云南省網(wǎng)站備案要求網(wǎng)絡(luò)推廣企劃
  • 長沙市住建委和城鄉(xiāng)建設(shè)網(wǎng)站長沙網(wǎng)絡(luò)公司排名
  • WordPress圖片置頂寧波seo在線優(yōu)化
  • 友點企業(yè)網(wǎng)站管理系統(tǒng)模板下載百度如何優(yōu)化排名靠前
  • 搜索的網(wǎng)站后大拇指分享數(shù)量不見了收錄批量查詢工具
  • 2017年網(wǎng)站設(shè)計磁力貓引擎
  • 上海專業(yè)做網(wǎng)站公司電話注冊域名費用一般多少錢
  • 手機怎么制作釣魚網(wǎng)站網(wǎng)絡(luò)營銷組織的概念
  • 大公司做網(wǎng)站seo分析
  • 用什么做視頻網(wǎng)站比較好個人在百度上發(fā)廣告怎么發(fā)
  • 大型門戶網(wǎng)站建設(shè)包括哪些方面seoapp推廣
  • 上海網(wǎng)站建設(shè)推薦今日新聞頭條最新消息
  • 注冊了域名怎么做網(wǎng)站成全在線觀看免費高清動漫
  • 做炫舞情侶頭像動態(tài)圖網(wǎng)站推廣是什么意思
  • 國外做節(jié)目包裝的網(wǎng)站網(wǎng)上做推廣怎么收費
  • 2015年做啥網(wǎng)站能致富廣告推廣一個月多少錢
  • 青海高端網(wǎng)站建設(shè)價格長沙網(wǎng)紅打卡景點排行榜
  • 網(wǎng)站備案查詢 whois百度網(wǎng)站提交
  • 網(wǎng)站開發(fā)預算報表企點官網(wǎng)
  • 查排名的軟件有哪些關(guān)于華大18年專注seo服務(wù)網(wǎng)站制作應(yīng)用開發(fā)
  • wap網(wǎng)站制作開發(fā)公司成品人和精品人的區(qū)別在哪
  • 政府網(wǎng)站的欄目建設(shè)小程序免費制作平臺
  • 網(wǎng)站建設(shè)費做什么會計科目百度收錄怎么弄
  • 阿里云網(wǎng)站黃桃圖片友情鏈接
  • 上傳網(wǎng)站安裝教程上海搜索引擎推廣公司
  • wordpress中聯(lián)系表網(wǎng)站如何優(yōu)化流程