Crd233's Notebook
Home
Courses
Languages
Math
CG
CV
AI
Reading
其它
— order: 1 —
1
HumanNeRF: Free-viewpoint Rendering of Moving People
from Monocular Video
●
时间:
2022.1 (
CVPR2022 oral)
●
参考
Human-NeRF
详细理解:从
LBS
到
Human-NeRF
和
论文随记
|
HumanNeRF
●
首先需要知道它干了什么
○
输入一个单目、运动人体的视频,经过离线的逐帧分割(需要手动清理)和三维位姿估计,基于优化的方法去训练网络参数(过拟
合到这个视频的人体表示),推理时在任意时刻暂停可以渲染出
360°
人体
○
方法是数据驱动的,端到端的,需要
3
D
位姿
refinement
但不需要
template model
●
基本思想是:
target / observation space
下的采样点
𝒙
,如果我们把它通过一个
motion field
逆变
换回
canonical space
𝒙
𝑐
,然后像
NeRF
那样过
MLP
得到密度和颜色,跟原本的采样点的密度和颜色应该是一一对应的
𝐹
𝑜
(
𝒙
,
𝒑
)
=
𝐹
𝑐
(
𝑇
(
𝒙
,
𝒑
)
)
○
注:
observation space
和
canonical space
下的点本身是一一对应,但实际上,
NeRF
的一个像素对应空间中多个采样点,这就做
不到一一对应了(回忆之前的
MipNeRF
等工作就是在缓解这件事情)。
Anyway
,
虽然这是固有缺陷,但至少大方向上能用
●
motion field
如何实现?
○
第一,把
motion field
解耦成骨骼驱动的变形
(
Skeletal motion)
和在其上的偏置
(
Non-rigid motion)
𝑇
(
𝒙
,
𝒑
)
=
𝑇
skel
(
𝒙
,
𝒑
)
+
𝑇
NR
(
𝑇
skel
(
𝒙
,
𝒑
)
,
𝒑
)
■
其中,
𝑝
=
(
𝐽
,
Ω
)
指
𝐾
个关节点的位置和局部关节旋转矩阵
○
第二,参照
Vid2Actor
把
SMPL
写死的蒙皮权重改成
volume
的(与空间相关的)
𝑤
𝑖
𝑜
(
𝒙
)
,学习一个逆变换
●
下面跟着
pipeline
来理一遍它的算法
1.
先用离线的
3
D body + camera pose
估计,出一个比较糙的
Body pose
𝒑
=
(
𝐽
,
Ω
)
2.
Pose Correction
:
𝐽
固定,优化
Ω
。相比直接去优化
Δ
Ω
(
𝒑
)
,用参数为
𝜃
pose
的
MLP
根据当前
Ω
去预测出更新值
Δ
Ω
(
𝒑
)
收敛更快
(这有点奇怪,一般估计
SMPL
参数时,基于优化的方法会比基于学习的方法更直接来着)
Δ
Ω
(
𝒑
)
=
MLP
𝜃
pose
(
Ω
)
𝑃
pose
(
𝒑
)
=
(
𝐽
,
Δ
Ω
(
𝒑
)
⊗
Ω
)
3.
Skeletal Motion
:
逆线性混合蒙皮,把
observation space
的点映射到
canonical space
,
怎么实现逆变换?
Given
𝑝
=
(
𝐽
,
Ω
)
:
𝐽
=
{
𝑗
𝑖
}
,
Ω
=
{
𝜔
𝑖
}
,
and predefined canonical pose
𝒑
𝑐
=
(
𝐽
𝑐
,
Ω
𝑐
)
𝑇
skel
(
𝒙
,
𝒑
)
=
∑
𝐾
𝑖
=
1
𝑤
𝑖
𝑜
(
𝒙
)
(
𝑅
𝑖
𝒙
+
𝒕
𝑖
)
[
𝑅
𝑘
0
𝒕
𝑘
1
]
=
∏
𝑖
∈
𝜏
(
𝑘
)
[
exp
(
𝜔
𝑐
𝑖
)
0
𝑗
𝑐
𝑖
1
]
{
{
{
{
{
∏
𝑖
∈
𝜏
(
𝑘
)
[
exp
(
𝜔
𝑖
)
0
𝑗
𝑖
1
]
}
}
}
}
}
−
1
○
比较
LBS
那个公式
𝐺
′
𝑘
(
𝜃
,
𝐽
(
𝛽
)
)
=
𝐺
𝑘
(
𝜃
,
𝐽
(
𝛽
)
)
𝐺
𝑘
(
𝜃
∗
,
𝐽
(
𝛽
)
)
−
1
,就是
𝜃
和
𝜃
∗
换了个位置,也就是逆
LBS
○
𝑤
𝑖
𝑜
依然是对第
𝑖
个骨骼的
blend weight
,
只是加个
𝑜
表示是把
observation space
中的任意点
𝒙
拉扯到
canonical space
去,而
且是根据
𝒙
可学习的;而不是原始公式中
𝑤
𝑘
,
𝑖
是对第
𝑘
个骨骼只对
𝑖
∈
𝑁
那么多个
rest pose template
顶点的
blend weight
(canonical space
→
observation space)
○
但是呢,如果我们对
𝑁
张图片都去学这么一个
observation space
下的
{
𝑤
𝑖
𝑜
(
𝒙
)
}
,很容易过拟合且泛化性不好。所以我们只学
canonical space
下的一组
𝑤
𝑖
𝑐
(
𝒙
)
,然后据此推出
𝑤
𝑖
𝑜
(
𝒙
)
𝑤
𝑖
𝑜
(
𝒙
)
=
𝑤
𝑖
𝑐
(
𝑅
𝑖
𝒙
+
𝒕
𝑖
)
∑
𝐾
𝑘
=
1
𝑤
𝑘
𝑐
(
𝑅
𝑘
𝒙
+
𝒕
𝑘
)
■
这个又怎么理解呢?实际上没有
LBS
那个又局部全局又两种
space
那么绕,就是说
——
所谓权重就是
𝐾
个骨骼不同的贡献,
那把
canonical space
下的不同贡献直接拿来当
observation space
下的贡献。这可能限制了
observation space
的表达精度,
但也限制了复杂度
■
后面
SHERF
直接就没有做可学习的
volume
,
而是直接用了
SMPL
写死的蒙皮权重
○
那这组
{
𝑤
𝑖
𝑐
(
𝒙
)
}
又是怎么学出来的呢?
■
最基本的想法是,用一个
MLP
,
输入
𝒙
,输出
𝐾
个权重,作者这里说要
𝐾
次
evaluations
我没看懂。但总之,
MLP
会比下
面用
CNN
慢
■
另一种想法是,把它们打包成一个
𝐾
+
1
通道的
CNN
来预测,用
CNN
网络结构的优势降低计算复杂度。这里再加了一个
background
通道,我们对
CNN
的输出做
channel-wise softmax
,
强制跨通道单位划分,视为一个分类问题,于是上式的分母
𝑓
(
𝒙
)
=
∑
𝐾
𝑘
=
1
𝑤
𝑘
𝑐
(
𝑅
𝑘
𝒙
+
𝒕
𝑘
)
可以据此视为采样点在人体表面的概率(如果很小,说明都分到背景类上去了)
■
再进一步优化,
volume
表示真的需要那么高精度吗?用
limited resolution
结合三线性插值重采样,虽然精度低一点,但能提
供
smoothness
来帮助正则化
4.
Non-Rigid Motion
:
原始
observation space
下的人是穿着衣服帽子等有纹理和细节的,而骨骼驱动、混合蒙皮这些都只基于
naked body
,
这里我们需要把这些细节在
canonical space
下修正回来
Δ
𝒙
(
𝒙
,
𝒑
)
=
𝑇
NR
(
𝑇
skel
(
𝒙
,
𝒑
)
,
𝒑
)
𝑇
NR
(
𝒙
,
𝒑
)
=
MLP
𝜃
NR
(
𝛾
(
𝒙
)
;
Ω
)
○
好像没什么好说的,就是被
𝑇
skel
牵扯完的点,加上经典的但略微修改了的(见后)
positional encoding
𝛾
(
⋅
)
,用
Ω
conditioned
MLP
预测一个偏移
○
注:
Pose Correction + Skeletal Motion + Non-Rigid Motion
这三步都是为了更好的实现逆
LBS
变换,让后面
NeRF Prediction
能更准
5.
NeRF Prediction
:
最后就是
NeRF
经典的
MLP
(
参数为
𝜃
𝑐
)预测密度和颜色了,我们刚刚做了那么多把一个
observation space
下的采样点
𝒙
映射到
canonical space
下
𝒙
𝑐
,丢进
MLP
预测出的结果可以直接当做
𝒙
的密度和颜色
○
体渲染就用
NeRF
那一套,不过对累计可见性的
𝛼
加了那个
𝑓
(
𝒙
)
的逻辑(非表面点即使它非常可见我们也不关心)
𝛼
𝑖
=
1
−
exp
(
−
𝜎
(
𝒙
𝑖
)
Δ
𝑡
𝑖
)
⟶
𝛼
𝑖
=
𝑓
(
𝒙
)
(
1
−
exp
(
−
𝜎
(
𝒙
𝑖
)
Δ
𝑡
𝑖
)
)
○
采样时没用分层采样的方法,因为
SMPL body
的先验已经把采样范围限定小很多了,只在
bounding box
里面进行采样
●
然后就是怎么训练了,给定视频输入帧
{
𝐼
1
,
𝐼
2
,
…
,
𝐼
𝑁
}
,离线预测出的
body poses
{
𝒑
1
,
𝒑
2
,
…
,
𝒑
𝑁
}
和
cameras
𝛽
1
,
𝛽
2
,
…
,
𝛽
𝑁
,求解
argmin
Θ
∑
𝑁
𝑖
=
1
ℒ
{
Γ
[
𝐹
𝑐
(
𝑇
(
𝒙
,
𝒑
𝑖
)
)
,
𝛽
𝑖
]
,
𝐼
𝑖
}
○
其中
Γ
是一个渲染器,
ℒ
是一个
loss function
,
优化对象
Θ
=
{
𝜃
𝑐
,
𝜃
skel
,
𝜃
NR
,
𝜃
pose
}
是所有网络参数
○
损失函数,以在一幅图像上采样的
𝐺
个大小为
𝐻
×
𝐻
的
patch
为粒度,每个
batch
渲染
𝐺
×
𝐻
×
𝐻
条射线(实验采用
𝐺
=
6
,
𝐻
=
3
2
)
ℒ
=
ℒ
LPIPS
+
𝜆
ℒ
MSE
○
虽然分了很多步骤,但还是端到端地训练
■
然而有一个问题是,由于
Non-Rigid Motion
在训练过程中过拟合到输入图像了,导致一部分
Skeletal Motion
也被它建模了(解
耦没做好),于是最终效果变差,在
unseen views
质量下降
■
解决办法是,从
Nerfies: Deformable Neural Radiance Fields
抄了个
positional encoding
的改进,在优化开始阶段
disable
non-rigid motions
,
慢慢地启用它(类似
Coarse-to-Fine
策略),具体来说:
𝛾
𝜏
(
𝒙
)
=
(
𝒙
,
…
,
𝑤
𝑘
(
𝜏
)
sin
(
2
𝑘
𝜋
𝒙
)
,
𝑤
𝑘
(
𝜏
)
cos
(
2
𝑘
𝜋
𝒙
)
,
…
,
𝑤
𝐿
(
𝜏
)
sin
(
2
𝐿
𝜋
𝒙
)
,
𝑤
𝐿
(
𝜏
)
cos
(
2
𝐿
𝜋
𝒙
)
)
𝑤
𝑘
(
𝜏
)
=
1
−
cos
(
clamp
(
𝜏
−
𝑘
,
0
,
1
)
𝜋
)
2
𝜏
(
𝑡
)
=
𝐿
max
(
0
,
𝑡
−
𝑇
𝑠
)
𝑇
𝑒
−
𝑇
𝑠
□
𝑡
是当前
iteration
,
𝑇
𝑠
,
𝑇
𝑒
分别代表什么时候开始启用和什么时候完全启用
frequency bands of positional encoding
训练神经网络不是黑盒子炼丹,是分步骤炼丹,要确保我们设计的网络正在干它该干的事情,要清楚每个网络的作用和意义,
有时候这种耦合行为的解决能大幅提高训练出来的质量,使人不得不认真对待
●
结果的话,还挺不错,达到了
SOTA
。
limitations
的话,我归纳了一下
1.
前面说的采样点那个缺陷;
2.
如果所有帧都不包含身体某一部分时会相应出现
artifacts
;
3.
方法比较依赖初始的位姿估计;
4.
如果包含运动模糊等比较难的
case
重建出的新视图可能会失败;
5.
非刚性运动比较依赖姿势,比如衣物宽松、长发飘飘就容易寄;
6.
光照上假设漫反射,旋转一定角度后外观不会明显变化;
7.
最后,需要人工干预去分割视频,把那些没用或是离谱的帧给剔除掉,限制了应用的广度
●
大体就是这样,不是很复杂,挺自然、符合直觉的一个把
NeRF
应用到人体的工作