论文阅读:DisCO Portrait Distortion Correction with Perspective-Aware 3D GANs
今天介绍一篇比较有趣的文章,通过 3D GAN inversion 来解决成像的透视畸变问题
Abstract
文章的摘要,一开始就介绍说,近距离成像的时候,人脸会产生比较明显的变形,使得最终的成像看起来不太自然。这篇文章提出了一种有效的方法来解决这个问题。首先,将 GAN inversion 作用于有形变的人脸图像上,联合优化得到对应的相机参数以及人脸的 latent code,为了解决这个联合优化的多义性问题,文章作者提出了一种顺序优化的策略,先对虚拟相机的焦距进行重参数化,然后再从一个较短的物距开始优化,最后还有一个几何的正则化。将 GAN inversion 优化好之后,就可以用 GAN inversion 实现不同相机参数下的图像生成,只要设置一个更加合理的焦距和物距,GAN inversion 生成的人脸,就可以看起来更加自然。
从上图来看,效果还可以
Method
这篇文章的目的是为了解决近距离成像的人脸透视畸变问题,文章的出发点其实是想通过调整成像的距离和相机的焦距来实现。为了达到这个目的,文章用了一个 perspective-aware 的 3D GAN inversion 的技术来解决这个问题,通过一个 3D GAN inversion,将输入的有透视形变的图像反解出其对应的 face latent code 和相机的参数,然后通过调整相机的参数,比如成像的物距和相机的焦距,再结合 face latent code,可以得到一个新的相机参数下的人脸图像,这部分应该是文章核心的创新点,但是为了让 3D GAN inversion 生成的人脸图像与原图的背景能很好的融合,文章又设计了一个后处理的流程,将背景与人脸区域重新进行融合。文章整体的流程如下图所示:
Preliminary
文章先介绍了一些背景知识,首先是介绍 StyleGAN。
-
StyleGAN 是一个非常经典的算法了,将一个从高斯分布中抽取的 512 维的随机向量 z ∈ R 512 \mathbf{z} \in \Bbb R^{512} z∈R512,映射到一个中间的隐向量 w ∈ R 512 \mathbf{w} \in \Bbb R^{512} w∈R512, w = H θ ( z ) \mathbf{w} = H_{\theta}(\mathbf{z}) w=Hθ(z)。隐向量所在的空间称为隐空间 W W W,隐向量 w \mathbf{w} w 控制生成器网络 G θ G_{\theta} Gθ 中 18 层特征的归一化,最后生成一张图像 I = G θ ( w ) = G θ ( H θ ( z ) ) I = G_{\theta}(\mathbf{w})=G_{\theta}(H_\theta(\mathbf{z})) I=Gθ(w)=Gθ(Hθ(z)),styleGAN 相比传统的 GAN 网络,通过增加一个隐向量 w \mathbf{w} w,来控制图像的不同的属性,从而达到编辑的作用。
-
GAN inversion,就是反过来,之前是通过输入一个随机变量,加上 隐向量 w \mathbf{w} w 的控制,从而实现图像的生成,现在这个 inversion,就是输入一张图像,希望能找到这张图像对应的隐向量:
w ^ = argmin w L ( G θ ( w ) , C r o p ( I r e a l ) ) (1) \mathbf{\hat{w}} = \text{argmin}_{\mathbf{w}} L(G_{\theta}(\mathbf{w}), Crop(I_{real})) \tag{1} w^=argminwL(Gθ(w),Crop(Ireal))(1)
- 3D GAN,相比 2D GAN 多了一个相机参数的输入,利用一个神经网络的渲染器,生成最终的图像:
I = R θ ( G θ ( w ) , c ) = R θ ( G θ ( H θ ( w , c ) ) , c ) (2) I = R_{\theta}(G_{\theta}(\mathbf{w}), \mathbf{c}) = R_{\theta}(G_{\theta}(H_{\theta}(\mathbf{w}, \mathbf{c})), \mathbf{c}) \tag{2} I=Rθ(Gθ(w),c)=Rθ(Gθ(Hθ(w,c)),c)(2)
其中的 c \mathbf{c} c 表示相机的内外参数
Perspective-aware 3D GAN inversion
文章中介绍说,3D GAN 结合相机参数,在生成图像方面展现了较大的潜力。不过,当利用单张输入图进行图像生成的时候,这个问题也很挑战,因为基于单张输入图,要同时预测相机参数和生成新的图像是一个 ill-posed 的问题,可能存在无数的组合,能够实现同样的效果。现有的 3D GAN inversion 的方法,主要处理的是远距离的成像问题,这种情况,人脸区域可以认为是在同样深度的一个平面,这种情况下,不同的相机参数组合下的人脸形态可以认为基本类似。这样可以放心地使用长焦距结合远物距实现人脸的重新生成。但是对于近距离的人像来说,因为透视形变的问题,对相机参数变得非常敏感,如果估计不准,将会导致最终生成的效果不对,为了解决这个问题,文章中对相机参数和 face latent code 都需要进行优化:
w ^ , c ^ = argmin w , c L ( R θ ( G θ ( w ) , c ) , C r o p ( I r e a l ) ) (3) \mathbf{\hat{w}}, \mathbf{\hat{c}} = \text{argmin}_{\mathbf{w}, \mathbf{c}} L(R_{\theta}(G_{\theta}(\mathbf{w}), \mathbf{c}), Crop(I_{real})) \tag{3} w^,c^=argminw,cL(Rθ(Gθ(w),c),Crop(Ireal))(3)
为了解决这个优化问题, 文章中结合了四种方式,focal length reparameterization(焦距的重参数化), starting from a short distance(从一个近距离开始), optimization scheduling(顺序优化), and landmark regularization (人脸 landmark 正则)
- Focal Length Reparameterization 虽然人脸形状,相机参数之间有很多种组合,但是不对的组合,可能会导致错误的人脸几何形状,文章为了减少自由度,以及搜索空间,将焦距与物距之间进行了某种关联,假设三维世界的一个点映射到相机坐标系上的关系满足如下公式:
[ p c 1 ] = [ R t 0 1 ] [ p w 1 ] (4) \begin{bmatrix} \mathbf{p}_c\\ 1 \end{bmatrix} = \begin{bmatrix} \mathbf{R} & \mathbf{t} \\ 0 & 1 \end{bmatrix} \begin{bmatrix} \mathbf{p}_w\\ 1 \end{bmatrix} \tag{4} [pc1]=[R0t1][pw1](4)
其中, R = [ r x , r y , r z ] T ∈ R 3 × 3 \mathbf{R} = [\mathbf{r_x}, \mathbf{r_y}, \mathbf{r_z}]^{T} \in \Bbb R^{3 \times 3} R=[rx,ry,rz]T∈R3×3 是一个旋转矩阵, t = [ t x , t y , t z ] T ∈ R 3 × 1 \mathbf{t} = [t_x, t_y, t_z]^{T} \in \Bbb R^{3 \times 1} t=[tx,ty,tz]T∈R3×1 是一个平移向量,上式是相机的外参矩阵,相机的内参矩阵,进一步将相机坐标系上的点,映射到图像坐标系:
z c [ u v 1 ] = K p c = [ f 0 c x 0 f c y 0 0 1 ] p c (5) z_c \begin{bmatrix} u\\ v\\ 1 \end{bmatrix} = \mathbf{K} \mathbf{p}_c = \begin{bmatrix} f & 0 & c_x \\ 0 & f & c_y \\ 0 & 0 & 1 \end{bmatrix} \mathbf{p}_c \tag{5} zc uv1 =Kpc= f000f0cxcy1 pc(5)
假设平移向量的初始值为 t z 0 t_{z0} tz0,初始焦距为 f 0 f_0 f0,拍摄物距为 d 0 d_0 d0,文章中假设只做 z z z 方向的平移,也就是只调整物距和焦距,不做角度的变化,所以可以得到下面的式子:
α = ( d 0 − ( t z 0 − t z ) ) / d 0 (6) \alpha = (d_0 - (t_{z0} - t_z)) / d_0 \tag{6} α=(d0−(tz0−tz))/d0(6)
这个式子表示了物距变化关系,与此同时,可以得到焦距的变化规律:
K = [ γ α f 0 c x 0 γ α f c y 0 0 1 ] (7) \mathbf{K} = \begin{bmatrix} \gamma\alpha f & 0 & c_x \\ 0 & \gamma \alpha f & c_y \\ 0 & 0 & 1 \end{bmatrix} \tag{7} K= γαf000γαf0cxcy1 (7)
其中的 γ \gamma γ 是一个可学习的参数,用于调整公式 (6) 的比例关系。
-
Starting from a short distance 为了更好的优化,文章中也提到了另外一个 trick,就是从一个更短的成像物距开始,因为文章中希望解决的是近距离成像的透视形变问题,同时,文章中假设平移的变化量 t z t_z tz 很小,根据平移变化量和公式 (6),可以推算出变化系数 α \alpha α,从而可以推算出焦距的变化。
-
Landmark regularization 文章中用到另外一个技术就是 landmark 正则,文章作者发现,单纯依靠纹理相关的 loss,在 3D GAN 中并不能很好的优化这类形变问题,因此文章中增加了这样一个 landmark 相关的loss,让网络对物距变化更敏感:
L l a n d m a r k ( m ) = ∑ i = 1 ∥ M ∥ ( log ( σ i 2 ) + ∥ m i − m i ′ ∥ 2 2 2 σ i 2 ) (8) L_{landmark}(m) = \sum_{i=1}^{\left \| \mathcal{M} \right \| } \left( \log(\sigma_{i}^{2}) + \frac{\left \| m_i - m_{i}' \right \|_{2}^{2} }{2\sigma_{i}^{2}} \right) \tag{8} Llandmark(m)=i=1∑∥M∥(log(σi2)+2σi2∥mi−mi′∥22)(8)
其中, m ∈ M m \in \mathcal{M} m∈M 是归一化之后的 3D landmark 点, ∥ M ∥ = 468 \left \| \mathcal{M} \right \| = 468 ∥M∥=468, σ \sigma σ 是可优化的参数,所以是每个 landmark 点提供了一个优化参数。
- Optimization scheduling face latent code 和成像物距的优化比较难同时优化,文章中为了解决这个问题,提出了一个顺序优化的策略:
依次优化相机参数,face latent code,最后优化生成器。
- step 0:利用一个 3DMM 模型对输入的人脸图像进行初步的拟合,得到初始的相机参数;然后将随机采样的 face latent code 进行平均作为 face latent code 的初始值;
- step 1:通过调整 $t_z $将物距初始化到一个比较近的距离,然后结合公式 (6),(7) 可以得到相应的焦距
- step 2:先将 face latent code,generator,以及 neural render 固定住,只优化相机参数,包括旋转和平移的参数。因为文章中已经将物距和焦距通过公式 (6),(7) 建立了联系,所以物距变化的时候,焦距也会随之自适应的变化
- step 3:当相机参数优化好之后,这一步会放开 face latent code,同时优化 face latent code 和相机参数
- step 4:等相机参数和 face latent code 都优化完之后,会将相机参数和 face latent code 固定住,只优化 generator 生成器
文章还给出了伪代码:
Perspective manipulation
当这些都优化好之后,就构建了一个与相机内外参有联系的 3D GAN inversion,这样,输入一张近距离拍摄的透视畸变图,可以解析出这张图的 face latent code,然后改变相机的参数,重新送入 3D GAN 模型,就可以渲染得到一张新的相机参数下的图像。
Geometry-aware stitching
对人脸区域通过 3D GAN inversion 处理之后,接下来需要将人脸区域与背景区域进行融合。
- Reprojection 这部分需要对整图基于同样的相机参数进行重投影。这个需要对整图的深度图与人脸区域的深度图进行对齐,文章先用一个单目深度估计模型,对原始的整图以及 3D GAN 渲染之后的人脸部分进行深度估计,然后通过如下的损失函数进行参数的优化:
arg min s , b ∑ ∥ s × C r o p ( d n e a r f u l l ⊙ Ψ ) + b − d n e a r G A N ∥ 2 2 (9) \argmin_{s, b} \sum \left \| s \times Crop(\mathbf{d}_{near}^{full} \odot \Psi) + b - \mathbf{d}_{near}^{GAN} \right \|_{2}^{2} \tag{9} s,bargmin∑ s×Crop(dnearfull⊙Ψ)+b−dnearGAN 22(9)
其中 s , b s, b s,b 表示表示待优化的尺度与平移参数, ⊙ \odot ⊙ 表示点乘操作, d n e a r G A N \mathbf{d}_{near}^{GAN} dnearGAN 表示经过 3D GAN 生成的人脸对应的深度图, Ψ \Psi Ψ 表示原始图像人脸的区域 mask, d n e a r f u l l \mathbf{d}_{near}^{full} dnearfull 表示原始输入图的深度图。
不过,单纯依靠这个尺度与平移参数还不能很好的对深度图进行融合,所以文章中还用到了 Poisson blending 做进一步的处理。
- Stitch tuning 接下来文章还进一步对生成器做了 fine tune,将重投影得到的图像 I w a r p r e a l \mathbf{I}_{warp}^{real} Iwarpreal去监督人脸的 generator,修正边界区域的生成效果:
L b o r d e r = ∥ I n o v e l r e f i n e ⊙ Ψ ~ − C r o p ( I r e a l w a r p ) ⊙ Ψ ~ ∥ 2 2 (10) L_{border} = \left \| \mathbf{I}_{novel}^{refine} \odot \tilde{\Psi} - Crop( \mathbf{I}_{real}^{warp}) \odot \tilde{\Psi} \right \|_{2}^{2} \tag{10} Lborder= Inovelrefine⊙Ψ~−Crop(Irealwarp)⊙Ψ~ 22(10)
同时,也对人脸内部区域进行约束:
L b o r d e r = ∥ I n o v e l r e f i n e ⊙ Ψ ^ − I n o v e l ⊙ Ψ ^ ∥ 2 2 (11) L_{border} = \left \| \mathbf{I}_{novel}^{refine} \odot \hat{\Psi} - \mathbf{I}_{novel} \odot \hat{\Psi} \right \|_{2}^{2} \tag{11} Lborder= Inovelrefine⊙Ψ^−Inovel⊙Ψ^ 22(11)
上面的 Ψ ~ \tilde{\Psi} Ψ~ 表示人脸边界区域, Ψ ^ \hat{\Psi} Ψ^ 表示人脸内部区域。