@
- 引言:什麼是新視角合成任務
- 定義
- 一般步驟
- NeRF的做法
- NeRF的三維重建
- NeRF的渲染
- 3DGS的三維重建
- 從一組圖片估計點雲
- 高斯點雲模型
- 球諧函式
- 引數最佳化
- 損失函式和引數最佳化
- 高斯點的數量控制(Adaptive Density Control)
- 新的問題
- 3DGS的渲染:快速可微光柵化
- 3DGS的限制
引言:什麼是新視角合成任務
定義
新視角合成(Novel View Synthesis),屬於計算機視覺領域,該任務要求:
- 輸入源影像(Source)
- 輸入源姿態(Source Pose)
- 輸入目標姿態(Target Pose)
最終獲得:
- 目標姿態對應的的圖片(Target)
無論是2020ECCV的best paper,NeRF,還是2023年爆火的3DGS,都是為了完成NVS任務。
一般步驟
- 三維重建: 從已有視角的影像中推斷出場景的三維幾何資訊,包括物體的形狀和位置。
- 渲染: 利用三維重建的資訊,透過渲染技術生成新視角下的影像,考慮光照和紋理等因素。
這兩個步驟是新視角合成的基本框架,涵蓋了幾何重建和影像合成的關鍵概念。在實踐中,可以根據具體應用的需求進一步細化這些步驟,例如加入光照模型、深度合成等處理,以提高合成影像的質量和真實感。
NeRF的做法
讓我們來以NeRF為例子,更加深刻地瞭解一個新視角合成任務的步驟。當然,筆者不會寫的特別詳細,否則這篇文章就變成NeRF的介紹了。如果對NeRF特別感興趣,可以閱讀筆者的另一篇文章。
NeRF的三維重建
NeRF成功最大因素就在於它借用了深度學習的東西去進行三維重建。簡單地說,NeRF利用多層感知機(MLP)建立了一個函式。
這個函式接受一個向量$(x,y,z,\theta,\phi )$作為輸入,其中,$(x,y,z)$表示這個點在空間中的座標,$(\theta,\phi )$表示觀察角度(俯仰角pitch和偏航角yaw)。它的輸出是$(RGB,\sigma )$。RGB很好理解,就是這個點的顏色。而$\sigma$,是一個被稱為體素密度的計算量。這兩個輸出的量是為了後面的體渲染做準備。
有了這個函式之後,對於三維空間中指定座標的任何一點,都可以知道它的$(RGB,\sigma )$。而且,由於使用的是MLP來表示這個函式,那麼這個函式就是連續的、可微分的,也就可以用反向傳播去最佳化。
NeRF的渲染
NeRF的渲染方式採用經典的體渲染。具體的演算法本文不再贅述。總而言之,體渲染需要三個引數作為輸入:
- 目標位姿
- 空間中每個位置的體素密度
- 空間中每個位置的RGB顏色值
然後輸出:
- 目標位姿對應的圖片
當然,這種方法也是可微的。
這種體渲染的方式需要以畫素為單位生成光線,然後在光線上對空間內的點進行取樣,因此,每個畫素點在渲染時都需要計算對應的光線,成本相當高昂,在渲染高解析度影像時幀率非常低下,無法做到實時渲染。
同樣基於這個原因,NeRF最佳化引數時,在源影像與生成影像上只會選擇一些畫素點,去計算RGB顏色值的損失,進行反向傳播,最佳化MLP的引數,而不是將所有畫素點都拿來計算損失。
3DGS的三維重建
從一組圖片估計點雲
3DGS使用SFM(Structure from Motion)方法完成了從一組圖片估計點雲的步驟,甚至不需要給出相機的位姿就可以獲得點雲。這是一種非常成熟的方法,由Schönberger和Frahm等人於2016年提出,已經封裝在COLMAP庫中,在3DGS開源的程式碼中可以直接呼叫。
此方法的具體內容不是本文要探討的,可閱讀原文獻。
高斯點雲模型
3DGS從獲得的稀疏點雲開始,建立並且最佳化高斯點雲
。每個高斯點包含以下幾個用來渲染的重要屬性:
- 點的座標,Position,即3D高斯函式的均值(Mean)
- 協方差矩陣,Covariance matrix,決定這個高斯點的形狀
- 不透明度,Opacity $\alpha$,在渲染時用到
- 球諧函式,Spherical harmonics,在3DGS中表示這個高斯點在任意視角下的顏色
球諧函式
球諧函式(Spherical Harmonics, SH)是一組定義在球面上的特殊函式,通常用來表示球面上的函式。球諧函式在圖形學、計算機圖形學和計算機影像等領域中廣泛應用。在3DGS中,球諧函式用於近似光照和顏色分佈。
雖然球諧函式是定義在球面上,但是這個函式的輸入並不是座標$(x,y,z)$,而是視角$(\theta,\phi )$,它的輸出是RGB顏色值。
只要給定了欲生成圖片的目標位姿之後,就可以知道這個點對應的視角$(\theta,\phi )$,從而根據這個函式計算這個點在圖片上應該呈現出的顏色。因此,球諧函式的引數也是最佳化的目標之一。
引數最佳化
- 使用所有的高斯點,使用源影像的位姿,渲染出影像
- 根據源影像和渲染影像,計算損失,並反向傳播進行最佳化。最佳化的物件有:
- 協方差矩陣,Covariance matrix
- 不透明度,Opacity $\alpha$
- 球諧函式,Spherical harmonics
- 對高斯點的數量進行控制,即進行克隆、分裂或者刪除
損失函式和引數最佳化
論文中,損失函式定義如下:
$$
\mathcal{L}=(1-\lambda) \mathcal{L}{1}+\lambda \mathcal{L}{\text {D-SSIM }}
$$
其中,$\mathcal{L}{1}$是實際圖片與渲染圖片的畫素值的L1範數;$\mathcal{L}{\text {D-SSIM }}$是Depth-aware Structural Similarity (D-SSIM) 損失,是一種基於結構相似性(SSIM)的損失函式,但考慮了深度資訊。SSIM 用於衡量兩幅影像在結構、亮度和對比度上的相似性。公式如下:
$$
\mathcal{L}{D-SSIM} = 1 - \frac{(2\mu{\hat{I}} \mu_I + C_1)(2\sigma_{\hat{I}I} + C_2)}{(\mu_{\hat{I}}^2 + \mu_I^2 + C_1)(\sigma_{\hat{I}}^2 + \sigma_I^2 + C_2)}
$$
其中:
- $\mu_{\hat{I}}$和$\mu_I$分別是渲染影像和真實影像的平均值。
- $\sigma_{\hat{I}}$ 和 $\sigma_I$分別是渲染影像和真實影像的方差。
- $\sigma_{\hat{I}I}$ 是渲染影像和真實影像之間的協方差。
- $C_1$ 和 $C_2$ 是用於穩定計算的常數。
然後,作者使用Adam一階最佳化器進行最佳化。
高斯點的數量控制(Adaptive Density Control)
- 刪除:在最佳化預熱之後,每一百次迭代,就會刪除幾乎透明的高斯點,即不透明度$\alpha$小於閾值$\epsilon_\alpha$的高斯。$\epsilon_\alpha$是個超引數,經驗上設定為0.0002。
- 克隆和分裂
- 對於重建不足的高斯點,克隆一個相同大小的副本,並且沿著位置梯度方向移動。
- 對於過度重建的高斯點,對它進行分裂,分裂時還需要確定比例,經驗上以超引數$\phi=1.6$作為這個比例。
新的問題
論文中,作者提出分裂高斯點的方法可能會導致密度的不合理增加。
In the first case we detect and treat the need for increasing both the total volume of the system and the number of Gaussians, while in the second case we conserve total volume but increase the number of Gaussians. Similar to other volumetric representations, our optimization can get stuck with floaters close to the input cameras; in our case this may result in an unjustified increase in the Gaussian density.
於是,作者設定了以下策略:
- 每迭代N=3000次,將所有高斯點的透明度$\alpha$修改為接近0的一個值。在最佳化時,$\alpha$會在需要時增加。同時,先前的
閾值刪除策略
也可以很好地剔除幾乎透明的高斯點。這裡的N
同樣是個超引數。
3DGS的渲染:快速可微光柵化
筆者主要參考了此篇綜述。
NeRF透過體渲染去生成新的影像,這要求為每個畫素都取樣很多空間點。這種方法在高解析度的影像合成中計算成本非常高昂,難以實現實時渲染速度。
與之形成鮮明對比的是,3DGS首先將空間中的3D高斯投影到基於畫素的影像平面上,這個過程被稱為潑濺(splatting)。隨後,3DGS對這些高斯進行排序並計算每個畫素的值。
- (a)潑濺步驟將 3D 高斯投射到影像空間。
- (b)3D高斯將影像劃分為多個不重疊的塊(tiles)。
- (c)3DGS複製覆蓋多個塊的高斯,為每個副本分配一個識別符號 ID。
- (d)透過渲染有序高斯,我們可以獲得所有畫素的值。渲染過程相互獨立。
3DGS的渲染分為以下幾步:
- 視錐剔除:給定指定的相機姿勢,此步驟確定哪些高斯點位於相機的視錐體之外。這樣做可以確保在後續計算中不涉及給定檢視之外的高斯點,從而節省計算資源。對應程式碼。
- 潑濺(splatting)。在這一步驟中,高斯點被投影到2D影像空間中進行渲染,如圖(a)所示。
給定檢視變換$\boldsymbol{W}$和3D協方差矩陣$\Sigma$ ,那麼投影的2D協方差矩陣$\Sigma^{\prime}$的計算公式如下:
$$
\Sigma^{\prime}=\boldsymbol{J} \boldsymbol{W} \Sigma \boldsymbol{W}^{\top} \boldsymbol{J}^{\top}
$$
其中,$\boldsymbol{J}$是射影變換的仿射近似的雅可比矩陣。對應程式碼。
- 以畫素為單位進行渲染。在深入討論使用多種技術來提升平行計算的最終版本的3D GS之前,我們首先闡述其更簡單的形式,以提供對其工作機制的洞察。給定畫素的位置$x$,可以透過檢視變換$\boldsymbol{W}$計算出它與所有重疊高斯的距離,即這些高斯的深度,形成一個排序的高斯列表$\mathcal{N}$(對應程式碼)。然後,採用alpha合成(對應程式碼)來計算這個畫素的最終顏色,對應公式如下:
$$
C=\sum_{i\in\mathcal{N}}c_i \alpha_i{\prime}\prod_{j=1}\left(1-\alpha_j^{\prime}\right)
$$
其中,$c_i$是球諧函式輸出的顏色,最終的不透明度$\alpha_i^{\prime}$是學習到的不透明度$\alpha_i$和高斯分佈的乘積結果(對應程式碼),對應計算公式如下:
$$
\alpha_i{\prime}=\alpha_i\times\exp\left(-\frac12(x-\boldsymbol{\mu}_i{\prime})\boldsymbol{\Sigma}_i{\prime{-1}}(\boldsymbol{x}-\boldsymbol{\mu}_i^{\prime})\right)
$$
其中,$x{\prime}$和$\boldsymbol{\mu}_i$是投影空間中的座標。
值得擔憂的是,與NeRFs相比,上述的渲染過程可能更慢,因為生成所需的有序列表難以並行化。實際上,這種擔憂是合理的;當使用這種簡單的逐畫素方法時,渲染速度可能會受到顯著影響。為了實現實時渲染,3DGS做出了幾個妥協,以適應平行計算。
Tiles
(影像塊)。為了避免為每個畫素計算有序列表的計算成本,3DGS將精度從畫素級別轉移到塊級別細節,如(b)所示。3DGS最初將影像劃分為多個不重疊的影像塊,這些影像塊在原始論文中被稱為tiles。每個塊包含16x16畫素。3DGS進一步確定哪些影像塊與這些投影的高斯(橢圓)相交。考慮到一個投影的高斯可能覆蓋多個塊,一種合理的方法是複製高斯,為每個副本分配一個識別符號(即塊ID),如(c)所示。- 並行化渲染。複製後,3DGS會將各自的塊ID與每個高斯檢視變換得到的深度值結合起來。這樣就得到了一個未排序的位元組列表,其中高位代表塊ID,低位表示深度。這樣,排序後的列表就可以直接用於渲染。(c)(d)提供了該概念的直觀演示。值得強調的是,每個塊和畫素的渲染都是獨立進行的,因此這一過程非常適合平行計算。另外一個好處是,每個塊的畫素都可以訪問一個公共的共享記憶體,並保持一個統一的讀取序列,從而提高渲染的並行執行效率。在原論文的官方實現中,該框架將塊和畫素的處理分別視為類似於CUDA程式設計架構中的block和thread。
3DGS的限制
一般來說,一個複雜場景需要由數百萬個高斯點表示。因此,3DGS的每個場景都需要GB級別的儲存空間。相比之下,NeRF的一個場景只需要MB級別的空間。
本文由部落格一文多發平臺 OpenWrite 釋出!