论文地址:https://arxiv.org/abs/2201.08845
源码地址:https://xharlie.github.io/projects/project_sites/pointnerf
体素神经渲染的方法生成高质量的结果非常耗时,且对不同场景需要重新训练(模型不具备泛化能力),而基于MVS的方法可以快速重建场景。Point NeRF结合了两种方法的优点,通过在基于光线进行的渲染管道中聚合场景表面附近的神经点特征来有效渲染。Point NeRF与可以与其他 3D 重建方法结合,并使用一种新的剪枝与生长机制来处理此类方法中的错误与异常值,其重建方法比NeRF提升了30倍。
经典的体渲染模型可以通过沿着可微的光线来计算预测的结果,如式1所示:
c=∑Mτj(1−exp(−σjΔj))rj,τj=exp(−∑t=1j−1σtΔt).(1)\begin{aligned} c & =\sum_{M} \tau_{j}\left(1-\exp \left(-\sigma_{j} \Delta_{j}\right)\right) r_{j}, \\ \tau_{j} & =\exp \left(-\sum_{t=1}^{j-1} \sigma_{t} \Delta_{t}\right) . \end{aligned}\tag{1}cτj=M∑τj(1−exp(−σjΔj))rj,=exp(−t=1∑j−1σtΔt).(1)
其中 τ\tauτ 表示透过率,σj\sigma_jσj 表示每个点的体密度,rjr_jrj 表示点的颜色 ,Δ\DeltaΔ 表示相邻采样点之间的距离。
辐射场是使用每个点的3D坐标与方向信息来表示空间中点的颜色与不透明度的一种方式。NeRF使用空间点的坐标与方向信息来回归辐射场。
神经点云表示为 P={(pi,fi,γi)∣i=1,...,N}P=\{(p_i, f_i, \gamma_i)|i=1, ...,N\}P={(pi,fi,γi)∣i=1,...,N} ,其中 pip_ipi 表示空间点的位置,fif_ifi 表示的局部场景信息的特征向量,γi∈[0,1]\gamma_i\in[0,1]γi∈[0,1] 表示点的置信度(点在物体表明的概率),Point NeRF使用神经点云来回归辐射场。
给定任意 3D 点的位置 xxx ,得到半径为 RRR 的范围内的 KKK 个邻域神经点。Point-NeRF可以被抽象为一个神经模块——任意点沿着任意方向从邻域点K回归出对应的 σ\sigmaσ (不透明度)与 rrr (RGB值):
(σ,r)=Point -NeRF(x,d,p1,f1,γ1,…,pK,fK,γK)(2)(\sigma, r)=\text { Point -} \operatorname{NeRF}\left(x, d, p_{1}, f_{1}, \gamma_{1}, \ldots, p_{K}, f_{K}, \gamma_{K}\right)\tag{2}(σ,r)= Point -NeRF(x,d,p1,f1,γ1,…,pK,fK,γK)(2)
PointNeRF使用类似PointNet的多层MLP结构来回归辐射场。
Per-Point processing:使用基于MLP的F来对 xxx 的邻域神经点处理,得到表示 xxx 位置的特征向量:
fi,x=F(fi,x−pi)(3)f_{i, x}=F(f_i, x-p_i)\tag{3}fi,x=F(fi,x−pi)(3)
使用了相对位置信息 x−pix-p_ix−pi 有利于提高模型的泛化能力。
View-dependent radiance regression: 对邻域内神经点的特征向量进行加权得到表示位置 xxx 的特征向量:
fx=∑iγiwi∑wifi,x, where wi=1∥pi−x∥. (4)f_{x}=\sum_{i} \gamma_{i} \frac{w_{i}}{\sum w_{i}} f_{i, x} \text {, where } w_{i}=\frac{1}{\left\|p_{i}-x\right\|} \text {. }\tag{4}fx=i∑γi∑wiwifi,x, where wi=∥pi−x∥1. (4)
其中 γi\gamma_iγi 为 iii 点的置信度。
使用基于MLP的 RRR 来回归得到 xxx 位置关于 ddd 方向的RGB值:
r=R(fx,d)(5)r = R(f_x, d)\tag{5}r=R(fx,d)(5)
Density regression:使用基于MLP的 TTT 来回归不透明度,并使用邻域点的不透明度进行加权,如式6所示:
σi=T(fi,x)σ=∑iσiγiwi∑wi,wi=1∥pi−x∥(6)\begin{aligned} \sigma_{i} & =T\left(f_{i, x}\right) \\ \sigma & =\sum_{i} \sigma_{i} \gamma_{i} \frac{w_{i}}{\sum w_{i}}, w_{i}=\frac{1}{\left\|p_{i}-x\right\|} \end{aligned}\tag{6}σiσ=T(fi,x)=i∑σiγi∑wiwi,wi=∥pi−x∥1(6)
Point-NeRF在3D层面进行体渲染,通过神经点引导模型在物体表面进行渲染,避免了在大范围深度场景采样,减小了计算量。
神经点的位置与置信度:以多张带有位姿的视图为输入,基于MVSNet获取点云与每个点的置信度:
{pi,γi}=Gp,γ(Iq,Φq,Iq1,Φq1,Iq2,Φq2,…)(7)\left\{p_{i}, \gamma_{i}\right\}=G_{p, \gamma}\left(I_{q}, \Phi_{q}, I_{q_{1}}, \Phi_{q_{1}}, I_{q_{2}}, \Phi_{q_{2}}, \ldots\right)\tag{7}{pi,γi}=Gp,γ(Iq,Φq,Iq1,Φq1,Iq2,Φq2,…)(7)
神经点特征:使用带有3个下采样层的 VGG 架构 GfG_fGf 来提取 2D 图像的多尺度特征图 IqI_qIq:
{fi}=Gf(Iq)(8)\left\{f_{i}\right\}=G_{f}\left(I_{q}\right)\tag{8}{fi}=Gf(Iq)(8)
初始点云的有空洞与离群点会影响渲染质量,使用点云剪枝与生长来对初始点云进行优化。
剪枝:使用置信度 γi\gamma_iγi 来对初始点云剪枝,每迭代 10k 次就给将 γi<0.1\gamma_i<0.1γi<0.1 的点云剔除。
同时使用置信度稀疏损失函数,使得模型在优化过程中将置信度趋近于 0 或趋近为 1:
Lsparse =1∣γ∣∑γi[log(γi)+log(1−γi)](9)\mathcal{L}_{\text {sparse }}=\frac{1}{|\gamma|} \sum_{\gamma_{i}}\left[\log \left(\gamma_{i}\right)+\log \left(1-\gamma_{i}\right)\right]\tag{9}Lsparse =∣γ∣1γi∑[log(γi)+log(1−γi)](9)
生长:使用点云生长方法来填充空洞区域的点云,选择渲染过程中不透明度最高的点 xjgx_{jg}xjg 为初始点:
αj=1−exp(−σjΔj),jg=argmaxjαj(10)\alpha_{j}=1-\exp \left(-\sigma_{j} \Delta_{j}\right), \quad j_{g}=\underset{j}{\operatorname{argmax}} \alpha_{j} \tag{10}αj=1−exp(−σjΔj),jg=jargmaxαj(10)
计算与 xjgx_{jg}xjg 最近的领域点的距离 ϵjg\epsilon_{jg}ϵjg,如果同时满足 αjg>Topacity\alpha_{jg}>T_{opacity}αjg>Topacity 与 ϵjg>Tdist\epsilon_{jg}>T_{dist}ϵjg>Tdist 则生长一个点,这些天满足在物体表面附近且远离其他点,通过重复迭代这种生长策略来得到覆盖物体表面的点云。
损失函数
Lopt =Lrender +aLsparse (11)\mathcal{L}_{\text {opt }}=\mathcal{L}_{\text {render }}+a \mathcal{L}_{\text {sparse }}\tag{11}Lopt =Lrender +aLsparse (11)
其中 Lrender \mathcal{L}_{\text {render }}Lrender 为渲染过程中的损失函数,α=2e−3\alpha=2e^{-3}α=2e−3
上一篇:终端配色-Docker容器终端