STORM代碼閱讀筆記

默認的 分辨率是 [160,240] ,基于 Transformer 的方法不能做高分辨率。

Dataloader

輸入是 帶有 pose 信息的 RGB 圖像

eval datasets

## 采樣幀數目 = 20
num_max_future_frames = int(self.timespan * fps) 
## 每次間隔多少個時間 timesteps 取一個context image
num_context_timesteps  = 4

按照STORM 原來的 setting, future_frames = 20 context_image 每次間隔4幀,所以是 context_frame_idx = [0,5,10,15], 在 target_frame 包含了 從[0,20]的所有20幀。

以這樣20 幀的 image 作為一個基本的 batch, 進行預測: 進入 model

所以,輸入網絡的 context_image 對應的 shape (1,4,3,160,240) 輸入4個時刻幀的 frame, 每一個 frame 有 3個相機;對應的 context_camtoworlds shape (1,4,3,4,4)

train datasets

第一幀 ID 隨機采樣, 之后的 context_image 每次間隔 5 幀,比如: [47 52 57 62]target·_frame_id 也是進行隨機選取:

  if self.equispaced:context_frame_idx = np.arange(context_frame_idx,context_frame_idx + num_max_future_frames,num_max_future_frames // self.num_context_timesteps,)

隨機在 num_future_id 里面 選擇 self.num_target_timesteps 選擇 4幀作為 target_image 的監督幀

Network

輸入網絡的 有3個 input: context_image, ray 和 time 的信息

  • context_image: (1,4,3,3,160,240)
  • Ray embedding (1,4,3,6,160,240)
  • time_embedding (1,4,3)
  • 將 image 和 ray_embedding 進行 concat 操作, 得到 x:(12,9,160,240)
 x = rearrange(x, "b t v c h w -> (b t v) c h w")
plucker_embeds = rearrange(plucker_embeds, "b t v h w c-> (b t v) c h w")
x = torch.cat([x, plucker_embeds], dim=1) ## (12,9,160,240)

然后經過3個 embedding , 將這些 feature 映射成為 token:

x = self.patch_embed(x)  # (b t v) h w c2x = self._pos_embed(x)  # (b t v) (h w) c2x = self._time_embed(x, time, num_views=v)

得到 x.shape (12,600,768), 表示一共有12張圖像,每個圖象 是 600 個 token, 每個 token 的 channel 是768. 然后將這些 token concat 在一起 得到了 (7200,768) 的 feature;

給得到的 token 分別加上可學習的 motion_token, affine_token 和 sky_token. 連接方式都是 concat
這樣得到的 feature 為 (7220,768)的 feature

if self.num_motion_tokens > 0:motion_tokens = repeat(self.motion_tokens, "1 k d -> b k d", b=x.shape[0])x = torch.cat([motion_tokens, x], dim=-2)
if self.use_affine_token:affine_token = repeat(self.affine_token, "1 k d -> b k d", b=b)x = torch.cat([affine_token, x], dim=-2)
if self.use_sky_token:sky_token = repeat(self.sky_token, "1 1 d -> b 1 d", b=x.shape[0])x = torch.cat([sky_token, x], dim=-2)
  • 使用 Transformer 進行學習, 得到的 feature 維度不變。:
 x = self.transformer(x)x = self.norm(x) ## shape(7220,768)

運行完之后,可以將學習到的 token提取出來:

if self.use_sky_token:sky_token = x[:, :1] ## (1,1,768)x = x[:, 1:]if self.use_affine_token:affine_tokens = x[:, : self.num_cams] ## (1,3,768)x = x[:, self.num_cams :]if self.num_motion_tokens > 0:motion_tokens = x[:, : self.num_motion_tokens]  ## (1,16,768)x = x[:, self.num_motion_tokens :]

在 Transformer 內部,沒有上采樣層,也可以實現 這種 per-pixel feature 的學習。
對于 x 進行 GS 的預測,得到 pixel_align 的高斯。 對于每個 patch, 得到的 feature 是 (12,600,768), 通過一個CNN,雖然通道數沒有變 (12,600,768), 但是之前 768 可以理解為全局的 語義, 之后的 768 為 一個patch 內部不同像素的語義,他們共享著 全局的 語義信息,但是每個pixel 卻又不一樣。 通過下面的 unpatchify 函數將將一個patch 的語義拆成 per-pixel 的語義,將每個768維token展開為8×8像素。

 b, t, v, h, w, _ = origins.shape## x_shape: (12,600,768)x = rearrange(x, "b (t v hw) c -> (b t v) hw c", t=t, v=v)## gs_params_shape: (12,600,768),這一步雖然通道沒變,但其實是將一個 token 的全局 語義,映射成## token 內部的像素級別的語義gs_params = self.gs_pred(x)## gs_params_shape: (12,12,160,240)### 關鍵步驟:unpatchify將每個768維token展開為8×8像素gs_params = self.unpatchify(gs_params, hw=(h, w), patch_size=self.unpatch_size)

根據 token展開的 per-pixel feature, 進行3DGS 的屬性預測

gs_params = rearrange(gs_params, "(b t v) c h w -> b t v h w c", t=t, v=v)
depth, scales, quats, opacitys, colors = gs_params.split([1, 3, 4, 1, self.gs_dim], dim=-1)
scales = self.scale_act_fn(scales)
opacitys = self.opacity_act_fn(opacitys)
depths = self.depth_act_fn(depth)
colors = self.rgb_act_fn(colors)
means = origins + directions * depths

除了3DGS 的一半屬性之外, storm 還額外預測了其他的運動屬性,包括:

其中: x: (1,7200,768) 代表 image_token, motion_tokens 是(1,16,768)代表 motion_token. 處理的大致思路是 motion_token 作為 query, 然后 image_token 映射的feature 作為 key, 去結合計算每一個 高斯的 moition_weightsmoition_bases

gs_params = self.forward_motion_predictor(x, motion_tokens, gs_params)
其中:
forward_flow = torch.einsum("b t v h w k, b k c -> b t v h w c", motion_weights, motion_bases)

moition_bases: shape: [1,16,3]
moition_weights: shape: [1,4,3,160,240,16]
forward_flow: shape: [1,4,3,160,240,3]: 是 weights 和bases 結合的結果

GS_param Rendering

  • 取出高斯的各項屬性,尤其是 means 和 速度 forward_v: STORM 假設 在這 20幀是出于 勻速直線運動, 其速度時不變的,可能并不合理。我們的方法直接預測 BBX,可能更為準確。
means = rearrange(gs_params["means"], "b t v h w c -> b (t v h w) c")
scales = rearrange(gs_params["scales"], "b t v h w c -> b (t v h w) c")
quats = rearrange(gs_params["quats"], "b t v h w c -> b (t v h w) c")
opacities = rearrange(gs_params["opacities"], "b t v h w -> b (t v h w)")
colors = rearrange(gs_params["colors"], "b t v h w c -> b (t v h w) c")
forward_v = rearrange(gs_params["forward_flow"], "b t v h w c -> b (t v h w) c")

這里得到的 高斯的 mean 是全部由 context_image 得到的, shape (46800,3), 但這其實是 4個 時刻context_frame_idx = [0,5,10,15], 得到的高斯,并不處于同一時間刻度。
通過比較 target_timecontext_time 之間的插值,去得到每一個 target_time 的 3D Gaussian 的坐標means_batched

  if tgt_time.ndim == 3:tdiff_forward = tgt_time.unsqueeze(2) - ctx_time.unsqueeze(1)tdiff_forward = tdiff_forward.view(b * tgt_t, t * v, 1)tdiff_forward_batched = tdiff_forward.repeat_interleave(h * w, dim=1)else:tdiff_forward = tgt_time.unsqueeze(-1) - ctx_time.unsqueeze(-2)tdiff_forward = tdiff_forward.view(b * tgt_t, t, 1)tdiff_forward_batched = tdiff_forward.repeat_interleave(v * h * w, dim=1)forward_translation = forward_v_batched * tdiff_forward_batchedmeans_batched = means_batched + forward_translation ## (20,460800,3) 

使用 gsplatbatch_rasterization 函數:

  rendered_color, rendered_alpha, _ = rasterization(means=means_batched.float(),  ## (20,460800,3)quats=quats_batched.float(),scales=scales_batched.float(),opacities=opacities_batched.float(),colors=colors_batched.float(),viewmats=viewmats_batched,  ## (20,3,4,4)Ks=Ks_batched,  ## (20,3,3,3)width=tgt_w,height=tgt_h,render_mode="RGB+ED",near_plane=self.near,far_plane=self.far,packed=False,radius_clip=radius_clip,)

bug 記錄:

當使用單個相機的時候,下面這段代碼會把 維度搞錯:

  if self.use_affine_token:affine = self.affine_linear(affine_tokens)  # b v (gs_dim * (gs_dim + 1))affine = rearrange(affine, "b v (p q) -> b v p q", p=self.gs_dim)images = torch.einsum("b t v h w p, b v p q -> b t v h w p", images, affine)gs_params["affine"] = affine

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

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

相關文章

2025電賽G題-發揮部分-參數自適應FIR濾波器

(1)測評現場提供由RLC元件(各1個)組成的“未知模型電路”。 按照圖3所示,探究裝置連接該電路的輸入和輸出端口,對該電路進行 自主學習、建模(不可借助外部測試設備),2分鐘…

Linux基礎 -- 內核快速向用戶態共享內核變量方案之ctl_table

系統化、可直接上手的 /proc/sys sysctl 接口使用文檔。內容涵蓋:機制原理、適用場景、ctl_table 字段詳解、常用解析器(proc_handler)完整清單與選型、最小樣例到進階(范圍校驗、毫秒→jiffies、字符串、數組、每網絡命名空間&a…

【RH124知識點問答題】第3章 從命令行管理文件

1. 怎么理解“Linux中一切皆文件”?Linux是如何組織文件的?(1)“Linux中一切皆文件”的理解和文件組織:在Linux中,“一切皆文件”指的是Linux將各種設備、目錄、文件等都視為文件對象進行管理。這種統一的文…

練習javaweb+mysql+jsp

只是簡單的使用mysql、簡單的練習。 有很多待完善的地方,比如list的servlet頁面,應該判斷有沒有用戶的。 比如list.jsp 應該循環list而不是寫死 index.jsp 樣式可以再優化一下的。比如按鈕就特丑。 本文展示了一個簡單的MySQL數據庫操作練習項目&#x…

使用Nginx部署前端項目

使用Nginx部署前端項目 一、總述二、具體步驟 2.1解壓2.2將原來的html文件夾的文件刪除,將自己的靜態資源文件放進去,點擊nginx.exe文件啟動項目2.3查看進程中是否有ngix的兩個進程在瀏覽器中輸入“localhost:端口號”即可訪問。 2.4端口被占用情況處理 …

【論文學習】KAG論文翻譯

文章目錄KAG: Boosting LLMs in Professional Domains via Knowledge Augmented Generation摘要1 引言2 方法論2.1 LLM友好型知識表示2.2 互索引機制2.2.1 語義分塊2.2.2 帶豐富語境的的信息抽取2.2.3 領域知識注入與約束2.2.4 文本塊向量與知識結構的相互索引2.3 邏輯形式求解…

24黑馬SpringCloud安裝MybatisPlus插件相關問題解決

目錄 一、前言 二、菜單欄沒有Other 三、Config Database里的dburl需要加上時區等配置 一、前言 在學習24黑馬SpringCloud的MybatisPlus-12.拓展功能-代碼生成器課程時,發現由于IDEA版本不同以及MybatisPlus版本更新會出現與視頻不一致的相關問題,本博…

人工智能賦能聚合物及復合材料模型應用與實踐

近年來,生成式人工智能(包括大語言模型、分子生成模型等)在聚合物及復合材料領域掀起革命性浪潮,其依托數據驅動與機理協同,從海量數據中挖掘構效關系、通過分子結構表示(如 SMILES、BigSMILES)…

MyBatis-Plus3

一、條件構造器和常用接口 1.wapper介紹 MyBatis-Plus 提供了一套強大的條件構造器(Wrapper),用于構建復雜的數據庫查詢條件。Wrapper 類允許開發者以鏈式調用的方式構造查詢條件,無需編寫繁瑣的 SQL 語句,從而提高開…

GXP6040K壓力傳感器可應用于醫療/汽車/家電

GXP6040K 系列壓力傳感器是一種超小型,為設備小型化做出貢獻的高精度半導體壓力傳感器,適用于生物醫學、汽車電子、白色家電等領域。采用標準的SOP6 和 DIP6 封裝形式,方便用戶進行多種安裝方式。 內部核心芯片是利用 MEMS(微機械…

Android ConstraintLayout 使用詳解

什么是 ConstraintLayoutConstraintLayout(約束布局)是 Android Studio 2.2 引入的一種新型布局,現已成為 Android 開發中最強大、最靈活的布局管理器之一。它結合了 RelativeLayout 的相對定位和 LinearLayout 的線性布局優勢,能…

Unity3D數學第三篇:坐標系與變換矩陣(空間轉換篇)

Unity3D數學第一篇:向量與點、線、面(基礎篇) Unity3D數學第二篇:旋轉與歐拉角、四元數(核心變換篇) Unity3D數學第三篇:坐標系與變換矩陣(空間轉換篇) Unity3D數學第…

UV安裝并設置國內源

文章目錄一、UV下載1.官方一鍵安裝2.github下載安裝二、更換國內鏡像源(加速下載)方法1:臨時環境變量(單次生效)方法2:永久配置(推薦)方法3:命令行直接指定源三、驗證鏡像…

1 前言:什么是 CICD 為什么要學 CICD

什么是 CI/CD 我的資源庫網站:https://www.byteooo.cn 在開發階段,許多編譯工具會將我們的源碼編譯可使用的文件。例如 vue-cli 的項目會被 webpack 打包編譯為瀏覽器的文件,Java 項目會被編譯為 .class/jar 文件以供服務器使用。 但是&am…

GitHub 趨勢日報 (2025年07月30日)

📊 由 TrendForge 系統生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日報中的項目描述已自動翻譯為中文 📈 今日獲星趨勢圖 今日獲星趨勢圖3579copyparty752supervision664500-AI-Agents-Projects483awesome403prompt-optim…

“非參數化”大語言模型與RAG的關系?

這個問題觸及了一個關鍵的技術細節,兩者關系密切,但層面不同: “非參數化”大語言模型是一個更廣泛的概念或類別,而RAG(Retrieval-Augmented Generation)是實現這一概念最主流、最具體的一種技術框架。 您可…

LeetCode Hot 100:15. 三數之和

題目給你一個整數數組 nums ,判斷是否存在三元組 [nums[i], nums[j], nums[k]] 滿足 i ! j、i ! k 且 j ! k ,同時還滿足 nums[i] nums[j] nums[k] 0 。請你返回所有和為 0 且不重復的三元組。注意:答案中不可以包含重復的三元組。示例 1&…

銀行回單識別應用場景剖析

銀行回單OCR識別技術通過自動化處理紙質或電子回單中的關鍵信息,顯著提升了金融、企業及個人場景下的數據管理效率。以下是其核心應用場景及價值的詳細剖析:一、企業財務場景自動化賬務處理對賬與記賬:OCR自動提取交易日期、金額、賬號等信息…

React的介紹和特點

1. React是什么? 1.1. React: 用于構建用戶界面的JavaScript庫1.2. React的官網文檔:https://zh-hans.reactjs.org/ 2. React的特點2.1. 聲明式編程: 目前整個大前端開發的模式:Vue、React、Flutter、SwiftUI只需要維護…

內核smmu學習

思考 smmu對外提供功能,設備驅動調用smmu 提供的api來配置頁表,那其他設備是如何和smmu交互的?iommu 作為將不同smmu硬件的一個抽象封裝,其它設備應該只能看到iommu這個封裝層,那么iommu這個子系統是如何進行抽象的&a…