论文地址:https://arxiv.org/abs/2201.08845
源码地址:https://xharlie.github.io/projects/project_sites/pointnerf
概述
体素神经渲染的方法生成高质量的结果非常耗时,且对不同场景需要重新训练(模型不具备泛化能力),而基于MVS的方法可以快速重建场景。Point NeRF结合了两种方法的优点,通过在基于光线进行的渲染管道中聚合场景表面附近的神经点特征来有效渲染。Point NeRF与可以与其他 3D 重建方法结合,并使用一种新的剪枝与生长机制来处理此类方法中的错误与异常值,其重建方法比NeRF提升了30倍。
Point-NeRF 场景表示
体渲染与辐射场
经典的体渲染模型可以通过沿着可微的光线来计算预测的结果,如式1所示:
c
=
∑
M
τ
j
(
1
−
exp
(
−
σ
j
Δ
j
)
)
r
j
,
τ
j
=
exp
(
−
∑
t
=
1
j
−
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 表示每个点的体密度,
r
j
r_j
rj 表示点的颜色 ,
Δ
\Delta
Δ 表示相邻采样点之间的距离。
辐射场是使用每个点的3D坐标与方向信息来表示空间中点的颜色与不透明度的一种方式。NeRF使用空间点的坐标与方向信息来回归辐射场。
基于点云的辐射场
神经点云表示为 P = { ( p i , f i , γ i ) ∣ i = 1 , . . . , N } P=\{(p_i, f_i, \gamma_i)|i=1, ...,N\} P={(pi,fi,γi)∣i=1,...,N} ,其中 p i p_i pi 表示空间点的位置, f i f_i fi 表示的局部场景信息的特征向量, γ i ∈ [ 0 , 1 ] \gamma_i\in[0,1] γi∈[0,1] 表示点的置信度(点在物体表明的概率),Point NeRF使用神经点云来回归辐射场。
给定任意 3D 点的位置
x
x
x ,得到半径为
R
R
R 的范围内的
K
K
K 个邻域神经点。Point-NeRF可以被抽象为一个神经模块——任意点沿着任意方向从邻域点K回归出对应的
σ
\sigma
σ (不透明度)与
r
r
r (RGB值):
(
σ
,
r
)
=
Point -
NeRF
(
x
,
d
,
p
1
,
f
1
,
γ
1
,
…
,
p
K
,
f
K
,
γ
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来对
x
x
x 的邻域神经点处理,得到表示
x
x
x 位置的特征向量:
f
i
,
x
=
F
(
f
i
,
x
−
p
i
)
(3)
f_{i, x}=F(f_i, x-p_i)\tag{3}
fi,x=F(fi,x−pi)(3)
使用了相对位置信息
x
−
p
i
x-p_i
x−pi 有利于提高模型的泛化能力。
View-dependent radiance regression: 对邻域内神经点的特征向量进行加权得到表示位置
x
x
x 的特征向量:
f
x
=
∑
i
γ
i
w
i
∑
w
i
f
i
,
x
, where
w
i
=
1
∥
p
i
−
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 为
i
i
i 点的置信度。
使用基于MLP的
R
R
R 来回归得到
x
x
x 位置关于
d
d
d 方向的RGB值:
r
=
R
(
f
x
,
d
)
(5)
r = R(f_x, d)\tag{5}
r=R(fx,d)(5)
Density regression:使用基于MLP的
T
T
T 来回归不透明度,并使用邻域点的不透明度进行加权,如式6所示:
σ
i
=
T
(
f
i
,
x
)
σ
=
∑
i
σ
i
γ
i
w
i
∑
w
i
,
w
i
=
1
∥
p
i
−
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层面进行体渲染,通过神经点引导模型在物体表面进行渲染,避免了在大范围深度场景采样,减小了计算量。
Point-NeRF 重建
Generating initial pointbased radiance fields
神经点的位置与置信度:以多张带有位姿的视图为输入,基于MVSNet获取点云与每个点的置信度:
{
p
i
,
γ
i
}
=
G
p
,
γ
(
I
q
,
Φ
q
,
I
q
1
,
Φ
q
1
,
I
q
2
,
Φ
q
2
,
…
)
(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 架构
G
f
G_f
Gf 来提取 2D 图像的多尺度特征图
I
q
I_q
Iq:
{
f
i
}
=
G
f
(
I
q
)
(8)
\left\{f_{i}\right\}=G_{f}\left(I_{q}\right)\tag{8}
{fi}=Gf(Iq)(8)
Optimizing pointbased radiance fields
初始点云的有空洞与离群点会影响渲染质量,使用点云剪枝与生长来对初始点云进行优化。
剪枝:使用置信度
γ
i
\gamma_i
γi 来对初始点云剪枝,每迭代 10k 次就给将
γ
i
<
0.1
\gamma_i<0.1
γi<0.1 的点云剔除。
同时使用置信度稀疏损失函数,使得模型在优化过程中将置信度趋近于 0 或趋近为 1:
L
sparse
=
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)
生长:使用点云生长方法来填充空洞区域的点云,选择渲染过程中不透明度最高的点
x
j
g
x_{jg}
xjg 为初始点:
α
j
=
1
−
exp
(
−
σ
j
Δ
j
)
,
j
g
=
argmax
j
α
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)
计算与
x
j
g
x_{jg}
xjg 最近的领域点的距离
ϵ
j
g
\epsilon_{jg}
ϵjg,如果同时满足
α
j
g
>
T
o
p
a
c
i
t
y
\alpha_{jg}>T_{opacity}
αjg>Topacity 与
ϵ
j
g
>
T
d
i
s
t
\epsilon_{jg}>T_{dist}
ϵjg>Tdist 则生长一个点,这些天满足在物体表面附近且远离其他点,通过重复迭代这种生长策略来得到覆盖物体表面的点云。
损失函数
L
opt
=
L
render
+
a
L
sparse
(11)
\mathcal{L}_{\text {opt }}=\mathcal{L}_{\text {render }}+a \mathcal{L}_{\text {sparse }}\tag{11}
Lopt =Lrender +aLsparse (11)
其中
L
render
\mathcal{L}_{\text {render }}
Lrender 为渲染过程中的损失函数,
α
=
2
e
−
3
\alpha=2e^{-3}
α=2e−3