論文閱讀-RaftStereo

文章目錄

  • 1 概述
  • 2 模塊說明
    • 2.1 特征抽取器
    • 2.2 相關金字塔
    • 2.3 多級更新算子
    • 2.4 Slow-Fast GRU
    • 2.5 監督
  • 3 效果

1 概述

在雙目立體匹配中,基于迭代的模型是一種比較主流的方法,而其鼻祖就是本文要講的RaftStereo。
先來說下什么是雙目立體匹配。給定極線矯正后的左圖和右圖(IL,IR)(I_L, I_R)(IL?,IR?),雙目立體匹配的目的就是估計一張視差圖dddddd中每個像素位置的視差值dxyd_{xy}dxy?表示在左圖ILI_LIL?(x,y)(x, y)(x,y)位置的像素與右圖IRI_RIR?中的(x?dxy,y)(x - d_{xy}, y)(x?dxy?,y)位置的像素在真實3D世界中對應于同一個物理點。換句話說,ddd表示了左圖和右圖在水平方向上的匹配關系。
有了視差圖ddd,左右相機的焦距fxf_xfx?和基線BBB,我們就可以通過式(1-1)得到左圖的深度圖DDD,這部分具體可以參考這篇。
D=Bfd(1-1)D = \frac{Bf}{d} \tag{1-1} D=dBf?(1-1)
RaftStereo的輸入是左右圖(IL,IR)(I_L, I_R)(IL?,IR?),輸出是視差ddd。由于視差ddd本身與相機參數無關,因此該方式訓練得到的模型可以應用于不同參數的相機。
RaftStereo參考了Raft,由特征抽取器,相關金字塔和基于GRU的迭代更新算子組成,可見圖1-1。
RAFT整體網絡結構

圖1-1 RAFT整體網絡結構

2 模塊說明

2.1 特征抽取器

如圖1-1所示,特征抽取器指的就是encoder,共有兩種encoder,一個叫做Feature Encoder,另一個叫做Context Encoder。
Feature Encoder同時作用于左、右圖像,將每幅圖像映射為密集特征圖,進而構建相關體。該網絡由一系列殘差塊和下采樣層組成,根據實驗中使用的下采樣層數不同,可生成分辨率為輸入圖像1/4或1/8且包含256個通道的特征圖。在Feature Encoder采用了Instance Normalization。
Context Encoder的架構與特征編碼器完全相同,不同之處在于使用Batch Normalization替代了Instance Normalization,并且僅在左圖上應用Context Encoder。上下文特征用于初始化更新算子的隱藏狀態,并在每次迭代更新算子時輸入GRU中。
關于feature encoder使用IN,context encoder使用BN的疑問。有人在github的issue上面也問了這個問題,可見https://github.com/princeton-vl/RAFT-Stereo/issues/17。
feature encoder中的IN比BN更有意義,因為作者希望僅從單個圖像中導出每組相關特征。context encoder也可以用IN,但是BN更考慮整個數據集的均值和方差。
有一個細節,作者的代碼中對BN進行了freeze_bn的操作,對應的代碼是m.eval()這只是將均值和方差限制為[0, 1],對于 γ\gammaγβ\betaβ 并沒有進行限制, γ\gammaγβ\betaβ 還是會進行梯度更新的。回顧一下BN的公式:
y=x?E[x]Var[x]+??γ+βy = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta y=Var[x]+??x?E[x]??γ+β

2.2 相關金字塔

(1)相關體
采用特征向量之間的點積作為視覺相似度的衡量指標,對具有相同y坐標的像素進行相關計算。給定分別從ILI_LIL?IRI_RIR?提取的特征圖f,g∈RH×W×Df, g ∈ R^{H×W×D}f,gRH×W×D,將內積運算限制在具有相同第一索引的特征向量之間進行,可得到相關體,如下式(2-1)所示。
Cijk=∑hfijh?gikh,C∈RH×W×W(2-1)C_{ijk} = \sum_h f_{ijh} \cdot g_{ikh}, C \in R^{H \times W \times W} \tag{2-1} Cijk?=h?fijh??gikh?,CRH×W×W(2-1)
式(2-1)看不明白的話,可以先不看iii,也就是我們只看yyy方向確定的情況下,同一行的相關體計算方法。很容易看出CjkC_{jk}Cjk?就表示左圖jjj位置與右圖kkk位置之間的相關性,這個相關性就是長度為DDD的向量fijf_{ij}fij?gikg_{ik}gik?的點積。
相關體的計算可以通過單個矩陣乘法來高效實現,這可以在GPU上輕松計算,并且只占用總運行時間的一小部分。
由于模型輸入是極線校正后的圖像,因此可以假設所有視差均為正值。因此,相關體的計算實際上只需針對正視差進行。然而,完整體計算的優勢在于其運算可通過矩陣乘法實現,而該運算經過高度優化。這簡化了整體架構設計,使作者能夠采用通用運算而非定制GPU內核。
(2)相關金字塔
通過重復對最后一維進行平均池化,構建了一個四層結構的相關體金字塔。金字塔的第kkk層是通過使用核尺寸為2、步長為2的一維平均池化操作得到,從第kkk層的體積生成的相關體Ck+1C_{k+1}Ck+1?,其維度為H×W×W/2kH×W×W/2^kH×W×W/2k。雖然金字塔的每一層都具有更大的感受野,但通過僅對最后一維進行池化處理,保留了原始圖像中的高分辨率信息,從而能夠恢復極其精細的結構特征。
(3)相關查找
為了在相關金字塔中建立索引,作者定義了一個類似于Raft中定義的查找算子LCL_CLC?。給定當前視差估計值ddd,作者會圍繞該估計值構建一個帶有整數偏移量的一維網格(如圖2-1所示)。這個網格用于從相關金字塔的每一層進行索引操作。
相關查找示意圖

圖2-1 相關查找示意圖

由于網格的值都是整數,在每個相關體取索引時使用了線性插值。取回的值最終被拼接到一個特征圖中。這部分的代碼可以參考下面的x0變量的計算方式。

class CorrBlock1D:def __call__(self, coords):r = self.radiuscoords = coords[:, :1].permute(0, 2, 3, 1)batch, h1, w1, _ = coords.shapeout_pyramid = []for i in range(self.num_levels):corr = self.corr_pyramid[i]dx = torch.linspace(-r, r, 2*r+1)dx = dx.view(2*r+1, 1).to(coords.device)x0 = dx + coords.reshape(batch*h1*w1, 1, 1, 1) / 2**iy0 = torch.zeros_like(x0)coords_lvl = torch.cat([x0,y0], dim=-1)corr = bilinear_sampler(corr, coords_lvl)corr = corr.view(batch, h1, w1, -1)out_pyramid.append(corr)out = torch.cat(out_pyramid, dim=-1)return out.permute(0, 3, 1, 2).contiguous().float()

2.3 多級更新算子

從初始點d0=0d_0 = 0d0?=0出發,預測一系列視差場{d1,...,dN}\{ d_1, ..., d_N \}{d1?,...,dN?}。在每次迭代中,利用當前視差估計值對相關體進行索引,生成一組相關特征。這些特征會依次通過兩個卷積層處理,同時當前視差估計值也會經過兩次卷積層處理。隨后將相關特征、視差特征和上下文特征拼接后輸入GRU,由GRU更新隱藏狀態。最終利用更新后的隱藏狀態來預測視差的動態變化。
(1)多個隱藏狀態
原始的Raft算法完全采用固定高分辨率進行更新。這種方法存在一個明顯缺陷:感受野面積會隨著GRU更新次數的增加而緩慢增長,這在處理具有大面積無紋理區域且局部信息匱乏的場景時容易引發問題。為解決這一難題,提出了一種多分辨率更新算子,該算子可同時作用于1/8、1/16和1/32分辨率的特征圖。實驗結果表明,采用這種多分辨率更新算子能顯著提升模型的泛化性能。
如圖2-2所示,GRU通過相互使用對方的隱藏狀態作為輸入進行交叉連接。相關查找和最終的視差更新由分辨率最高的GRU完成。
多級GRU

圖2-2 多級GRU

(2)上采樣
預測的視差場分辨率是輸入圖像的1/4或1/8。為了輸出全分辨率視差圖,采用了與Raft相同的凸上采樣方法。RAFT-Stereo將全分辨率視差值視為其粗分辨率鄰近點3x3網格的凸組合結果,而凸組合權重則由最高分辨率GRU進行預測。
上采樣部分的代碼為

def upsample_flow(self, flow, mask):""" Upsample flow field [H/8, W/8, 2] -> [H, W, 2] using convex combination """N, D, H, W = flow.shapefactor = 2 ** self.args.n_downsamplemask = mask.view(N, 1, 9, factor, factor, H, W)mask = torch.softmax(mask, dim=2)up_flow = F.unfold(factor * flow, [3,3], padding=1)up_flow = up_flow.view(N, D, 9, 1, 1, H, W)up_flow = torch.sum(mask * up_flow, dim=2)up_flow = up_flow.permute(0, 1, 4, 2, 5, 3)return up_flow.reshape(N, D, factor*H, factor*W)

其中的mask就是最高分辨率GRU預測得到的凸組合權重。

2.4 Slow-Fast GRU

將GRU更新到1/8分辨率的隱藏狀態,其浮點運算量大約是更新1/16分辨率隱藏狀態的四倍。為了利用這一特性提升推理速度,作者對RAFT-Stereo模型進行了優化,每當更新1/8分辨率隱藏狀態時,就會同步多次更新1/16和1/32分辨率的隱藏狀態。在KITTI分辨率圖像上進行32次GRU更新后,這一改進使RAFTStereo的運行時間從0.132秒縮短至0.05秒,效率提升達52%。
這種改進使RAFT-Stereo在實時立體視覺方面具有競爭力的性能,而運行的方法快一個數量級,如下表2-1的Slow-Fast行所示。
消融實驗

表2-1 消融實驗

作者發現,通過增加低分辨率GRU的迭代次數并減少高分辨率GRU的迭代次數,在略微降低精度的情況下,RAFT-Stereo的運行時間顯著縮短。Slow-Fast版本的RaftStereo分別將最低、中等和最高分辨率的隱藏狀態更新30次、20次和10次,而Regular版本則將每個隱藏狀態更新32次。無論是Slow-Fast還是Regular版本,都使用相同的模型權重。Slow-Fast-GRU這部分的代碼如下所示

for itr in range(iters):coords1 = coords1.detach()corr = corr_fn(coords1) # index correlation volumeflow = coords1 - coords0with autocast(enabled=self.args.mixed_precision):if self.args.n_gru_layers == 3 and self.args.slow_fast_gru: # Update low-res GRUnet_list = self.update_block(net_list, inp_list, iter32=True, iter16=False, iter08=False, update=False)if self.args.n_gru_layers >= 2 and self.args.slow_fast_gru:# Update low-res GRU and mid-res GRUnet_list = self.update_block(net_list, inp_list, iter32=self.args.n_gru_layers==3, iter16=True, iter08=False, update=False)net_list, up_mask, delta_flow = self.update_block(net_list, inp_list, corr, flow, iter32=self.args.n_gru_layers==3, iter16=self.args.n_gru_layers>=2)

從代碼中不難看出,self.args.slow_fast_gru=True時,計算量反而會增加,并沒有起到提速的效果。這是為啥呢?
使用Slow-Fast-GRU時的做法是將總的迭代次數減少,32->7,但是這樣的效果會變差。但現在模型的做法都是在Slow-Fast-GRU為True的情況下,同時設置迭代次數為32,這其實更慢了。在github issue上面其他人的提問和作者解答可見https://github.com/princeton-vl/RAFT-Stereo/issues/25。

2.5 監督

作者在預測序列{d1,...,dN}\{ d_1, ..., d_N \}{d1?,...,dN?}中,通過指數級遞增的權重對預測視差與真實視差之間的L1L1L1距離進行監督。給定真實視差dgtd_{gt}dgt?時,損失函數定義為
L=∑i=1NγN?i∣∣dgt?di∣∣1(2-2)L = \sum^N_{i=1} \gamma^{N-i} || d_{gt} - d_i ||_1 \tag{2-2} L=i=1N?γN?i∣∣dgt??di?1?(2-2)
其中,γ=0.9\gamma = 0.9γ=0.9

3 效果

作者對比了RaftStereo與其他雙目深度估計算法的泛化能力,這些算法均在虛擬場景數據集Sceneflow上進行訓練,并在真實場景數據集上進行測試,可見表3-1。表中的數值表示誤差,即誤差超過指定閾值的像素百分比。作者采用標準評估閾值是KITTI為3像素,Middlebury為2像素,ETH3D為1像素。
泛化能力效果對比

表3-1 泛化能力效果對比

不同模型之間的可視化效果對比可見圖3-1,可見RaftStereo對于細結構的物體效果更好。
可視化效果對比

圖3-1 可視化效果對比

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/90768.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/90768.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/90768.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內存優化:從堆分配到零拷貝的終極重構

引言 在現代高性能軟件開發中,內存管理往往是性能優化的關鍵戰場。頻繁的堆內存分配(new/delete)不僅會導致性能下降,還會引發內存碎片化問題,嚴重影響系統穩定性。本文將深入剖析高頻調用模塊中堆分配泛濫導致的性能塌方問題,并…

【GoLang#2】:基礎入門(工具鏈 | 基礎語法 | 內置函數)

前言:Go 的一些必備知識 1. Go 語言命名 Go的函數、變量、常量、自定義類型、包(package)的命名方式遵循以下規則: 首字符可以是任意的Unicode字符或者下劃線剩余字符可以是Unicode字符、下劃線、數字字符長度不限 Go 語言代碼風格及開發事項代碼每一行結…

Bert項目--新聞標題文本分類

目錄 技術細節 1、下載模型 2、config文件 3、BERT 文本分類數據預處理流程 4、對輸入文本進行分類 5、計算模型的分類性能指標 6、模型訓練 7、基于BERT的文本分類預測接口 問題總結 技術細節 1、下載模型 文件名稱--a0_download_model.py 使用 ModelScope 庫從模型倉…

sendfile系統調用及示例

好的,我們繼續學習 Linux 系統編程中的重要函數。這次我們介紹 sendfile 函數,它是一個高效的系統調用,用于在兩個文件描述符之間直接傳輸數據,通常用于將文件內容發送到網絡套接字,而無需將數據從內核空間復制到用戶空…

數據結構習題--刪除排序數組中的重復項

數據結構習題–刪除排序數組中的重復項 給你一個 非嚴格遞增排列 的數組 nums ,請你 原地 刪除重復出現的元素,使每個元素 只出現一次 ,返回刪除后數組的新長度。元素的 相對順序 應該保持 一致 。然后返回 nums 中唯一元素的個數。 方法&…

Docker的容器設置隨Docker的啟動而啟動

原因也比較簡單,在docker run 的時候沒有設置–restartalways參數。 容器啟動時,需要增加參數 –restartalways no - 容器退出時,不重啟容器; on-failure - 只有在非0狀態退出時才從新啟動容器; always - 無論退出狀態…

JWT安全機制與最佳實踐詳解

JWT(JSON Web Token) 是一種開放標準(RFC 7519),用于在各方之間安全地傳輸信息作為緊湊且自包含的 JSON 對象。它被廣泛用于身份驗證(Authentication)和授權(Authorization&#xff…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘ipython’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘ipython’問題 摘要 在開發過程中,我們常常會遇到pip install報錯的問題,其中一個常見的報錯是 ModuleNotFoundError: No module named…

從三維Coulomb勢到二維對數勢的下降法推導

題目 問題 7. 應用 9.1.4 小節描述的下降法,但針對二維的拉普拉斯方程,并從三維的 Coulomb 勢出發 KaTeX parse error: Invalid delimiter: {"type":"ordgroup","mode":"math","loc":{"lexer&qu…

直播一體機技術方案解析:基于RK3588S的硬件架構特性?

硬件配置??主控平臺??? 搭載瑞芯微RK3588S旗艦處理器(四核A762.4GHz 四核A55)? 集成ARM Mali-G610 MP4 GPU 6TOPS算力NPU? 雙通道LPDDR5內存 UFS3.1存儲組合??專用加速單元??→ 板載視頻采集模塊:支持4K60fps HDMI環出采集→ 集…

【氮化鎵】GaN取代GaAs作為空間激光無線能量傳輸光伏轉換器材料

2025年7月1日,西班牙圣地亞哥-德孔波斯特拉大學的Javier F. Lozano等人在《Optics and Laser Technology》期刊發表了題為《Gallium nitride: a strong candidate to replace GaAs as base material for optical photovoltaic converters in space exploration》的文章,基于T…

直播美顏SDK動態貼紙模塊開發指南:從人臉關鍵點識別到3D貼合

很多美顏技術開發者好奇,如何在直播美顏SDK中實現一個高質量的動態貼紙模塊?這不是簡單地“貼圖貼臉”,而是一個融合人臉關鍵點識別、實時渲染、貼紙驅動邏輯、3D骨骼動畫與跨平臺性能優化的系統工程。今天,就讓我們從底層技術出發…

學習游戲制作記錄(劍投擲技能)7.26

1.實現瞄準狀態和接劍狀態準備好瞄準動畫,投擲動畫和接劍動畫,并設置參數AimSword和CatchSword投擲動畫在瞄準動畫后,瞄準結束后才能投擲創建PlayerAimSwordState腳本和PlayerCatchSwordState腳本并在Player中初始化:PlayerAimSwo…

【c++】問答系統代碼改進解析:新增日志系統提升可維護性——關于我用AI編寫了一個聊天機器人……(14)

在軟件開發中,代碼的迭代優化往往從提升可維護性、可追蹤性入手。本文將詳細解析新增的日志系統改進,以及這些改進如何提升系統的實用性和可調試性。一、代碼整體背景代碼實現了一個基于 TF-IDF 算法的問答系統,核心功能包括:加載…

visual studio2022編譯unreal engine5.4.4源碼

UE5系列文章目錄 文章目錄 UE5系列文章目錄 前言 一、ue5官網 二.編譯源碼中遇到的問題 前言 一、ue5官網 UE5官網 UE5源碼下載地址 這樣雖然下載比較快,但是不能進行代碼git管理,以后如何虛幻官方有大的版本變動需要重新下載源碼,所以我們還是最好需要visual studio2022…

vulhub Earth靶場攻略

靶場下載 下載鏈接:https://download.vulnhub.com/theplanets/Earth.ova 靶場使用 將壓縮包解壓到一個文件夾中,右鍵,用虛擬機打開,就創建成功了,然后啟動虛擬機: 這時候靶場已經啟動了,咱們現…

Python訓練Day24

浙大疏錦行 元組可迭代對象os模塊

Spring核心:Bean生命周期、外部化配置與組件掃描深度解析

Bean生命周期 說明 程序中的每個對象都有生命周期,對象的創建、初始化、應用、銷毀的整個過程稱之為對象的生命周期; 在對象創建以后需要初始化,應用完成以后需要銷毀時執行的一些方法,可以稱之為是生命周期方法; 在sp…

日語學習-日語知識點小記-進階-JLPT-真題訓練-N1階段(1):2017年12月-JLPT-N1

日語學習-日語知識點小記-進階-JLPT-真題訓練-N1階段(1):2017年12月-JLPT-N1 1、前言(1)情況說明(2)工程師的信仰(3)真題訓練2、真題-2017年12月-JLPT-N1(1&a…

(一)使用 LangChain 從零開始構建 RAG 系統|RAG From Scratch

RAG 的主要動機 大模型訓練的時候雖然使用了龐大的世界數據,但是并沒有涵蓋用戶關心的所有數據, 其預訓練令牌(token)數量雖大但相對這些數據仍有限。另外大模型輸入的上下文窗口越來越大,從幾千個token到幾萬個token,…