目录

  • 1. 前言
  • 2. 相关研究介绍
  • 3. 文章提出的方法
    • 3.1 渲染器结构(GAR)
    • 3.2 渲染器损失函数
      • 3.2.1 法线一致性损失
      • 3.2.2 面部关键点一致性损失
      • 3.2.3 身份损失
      • 3.2.4 总的损失函数
    • 3.3 开始重建

1. 前言

这篇文章是2021年CVPR的oral,方法名翻译为“基于反向生成对抗渲染的三维面部重建”,个人觉得它里面提供的思路挺新颖的,并且也开放了源码,点此查看

2. 相关研究介绍

目前的主流人脸三维重建技术大致分为两类方式,基于学习的方式与基于优化的方式。基于学习的方式,是借助CNN来回归控制人脸三维结构的3DMM系数,但是缺点便是依赖三维标注数据集,而3DMM的真实值其实是很难获取到的,这种三维数据集非常稀缺;基于优化的方式,是将所输入的二维人脸图像看做是一个生成的过程,由一系列的参数控制,如albedo(反照率,可以理解为人脸表面的不加光照的基础颜色)、纹理、光照、观察角度等,按照特定的渲染图像的法则最终计算出来二维人脸图像,而这样我们就可以通过比较渲染图像与输入图像的差异进行优化了,但是缺点是所使用的渲染图像法则决定了重建效果的上限,这种法则其实是简化了很多复杂过程的。
最近的可微分渲染应用优化了以上两种方法,比如我使用3DMM系数渲染后的图像,可以通过比较与输入图像的差异进行优化(相当于结合了两种方法的好处,不再依赖数据集,有篇参考文章《Accurate 3d face reconstruction with weakly-supervised learning: From single image to image set》CVPR Workshop 2019),当然可微分渲染也有两个缺点,一是渲染的过程是人为指定的,像基于优化的方法一样,渲染出的图像不是很真实,二是可微分渲染器很难优化,它只能将误差反向传播给局部顶点(个人理解为很难调控全局的信息,比如这个人的身份特征)。

如上图所示,文章将自己的方法渲染出的图像与最近的一些方法进行了比较,可以看到3DDFA使用的渲染(得到最终的3DMM系数后进行普通渲染)和GANFIT使用的渲染(通过可微渲染一步步优化3DMM系数)生成的图像都不是那么真实。这种所谓不真实的渲染方法文中称作graphics-based,就是图形学中通用的栅格化渲染,其实我们玩过很多的3A大作游戏,虽然图像很逼真,但是总是感觉和现实有那么一点差距,作者这里就认为是图形学里的渲染管线结构本身导致了这种不真实,如果替换成神经网络可能结果会更加逼真一点(可惜在图形学里是不可能用神经网络进行渲染的)。虽然有些文章对渲染过程做了优化,还是很难解决这种问题,如《Neural 3d mesh renderer》CVPR 2018、《Soft rasterizer: Differentiable rendering for unsupervised singleview mesh reconstruction》。
那么既然普通渲染、可微渲染太假,那么我将其升级为神经网络渲染会如何呢,也不太行,如上图d的DFG方法《Disentangled and controllable face image generation via 3d imitative-contrastive learning》CVPR 2020所示,输入是3dmm系数,但是神经网络渲染器要理解3DMM系数这种抽象的东西实在太难了,以至于生成的人脸和我们想要的人脸根本不是一个人。

3. 文章提出的方法

在读之前,建议先了解下styleGAN和styleGAN v2这两篇文章,因为后面的方法是基于style GAN v2的结构的。
先简单说一下个人理解的本文思想脉络:

  1. 如果我直接采用一般的渲染方式(图形学里通用的栅格化渲染),通过比较渲染图像与原图的像素差异,去优化控制人脸的3DMM系数(形状系数),会产生问题:因为本身这种渲染的方式渲染的图像根本就不真实,所以我再继续去比较像素差异的话肯定对于优化的效果来说没有说服力(文中称会产生domainshift noise)。所以这篇文章在渲染方式上进行了改进,基于自己改进的style GAN v2的结构来进行渲染,这样一来,我先保证了渲染出的图像足够真实,那么在能够渲染出真实图像的基础上按照像素差异去优化3DMM系数,肯定就有说服力了。
  2. 这个渲染器借鉴了style GAN v2的结构,输入是z(latent code,在style GAN里面控制着生成人脸图像的风格,如肤色、性别、年龄等,在本文里,作者设计了一种loss方法让他尽量控制人脸形状之外的人脸属性,如人脸纹理)、noise(在style GAN 里面保证生成图像细节方面的多样性)、normal map(法线贴图,style GAN里面没有这种东西,在本文里作者也是在训练时用loss方法让其控制人脸的形状;而法线贴图可以通过3DMM系数的形状与表情系数、拍摄角度系数得到)。通过类似于style GAN的训练方式,得到了这样一个效果较好的渲染器。
  3. 当然在这个渲染器的训练过程中,得考虑尽量让渲染出的图像的形状由法线贴图控制,还得考虑别让z和法线贴图的作用太相似(称之为解耦合),因为我们希望z和法线贴图控制的是图像的不同属性,这些问题作者通过设计了不同的损失函数来解决。这个渲染器训练解决的是什么问题呢,是根据输入,去尽量生成像训练数据集里面人脸的图像(或者说就是去尽量生成真实人脸图像),而毕竟是GAN网络嘛,数据集图像是没有标注的,整个过程是自监督训练。
  4. 有了这样一个完美的渲染器,下面就可以固定渲染器里面的各种参数不动,进行渲染器的各种输入参数的优化了,主要优化项包括z(latent code,可以相当于三维人脸的纹理)、3DMM形状与表情系数和姿态(就是相机拍摄角度)系数,其中虽然法线贴图作为渲染器输入,应该优化的是法线贴图才对,但是毕竟法线贴图背后是由3DMM系数控制的,所以就当做优化这些3DMM系数了。
  5. 其中在优化的时候还有个问题,渲染器的输入参数z是随机初始化的吗?万一最终结果陷入局部极小值怎么办?于是作者把这个渲染器给反转过来(就搞了个渲染器的对称结构,比如上采样改成下采样这样,有篇文章《 Seeing what a gan cannot generate》 ICCV 2019 就讨论了如何反转GAN网络获得latent code),将要进行三维重建的输入图像先当做渲染结果,预测一个靠谱的输入来进行渲染器的输入参数初始化,然后将这个初始化输入丢入渲染器进行渲染,按理说得到的渲染图像和输入图像应该八九不离十了,这时再进一步优化微调,应该就能避免局部极小值这样的问题了。
  6. 刚刚把z的初始化给解决了,那法线贴图该如何初始化呢,或者说3DMM系数该如何初始化呢,很简单,1999年提出3DMM系数的那篇文章就提出了一种基于2D关键点拟合3DMM系数的方法,直接搬过来用就行了~
  7. 最后我们回过神来想想,这篇文章因为使用的渲染方式与传统不一样,所以三维人脸的表示方式也与传统不太一样,比如三维人脸的纹理给换成了z进行表示,那我就无法导出obj文件了呀。不过好在三维人脸的3DMM形状系数与姿态系数还和传统一样,如果我想进行三维人脸的编辑的话也能勉强行得通,并且我的渲染结果比传统方法更真实,算是有失也有得吧~

梳理完文章的思想脉络,我们再来看具体的设计方法:

3.1 渲染器结构(GAR)


图中左边部分就是生成对抗渲染器(GAR)的结构图,整个渲染器的结构基于style GAN v2进行改进得到,在渲染的时候(黑线部分),接收z、noise、normal map三个输入,其中这三个输入在每一个渲染块都会产生作用(如果仅仅在输入渲染块产生作用的话,那么经过一层一层之后对最终结果就影响甚微了,这也是style GAN设计的核心思想),网络中的C1是一个固定的输入,相当于初始的特征图(4∗44*44∗4分辨率,512通道),每经过一层渲染块,分辨率会加倍,8∗88*88∗8到16∗1616*1616∗16一直到1024∗10241024*10241024∗1024。而每一层渲染块的具体结构如下图所示:

之前的z经过8层MLP转换到了参数w,可以认为将z所蕴含的特征进行了展开(因为z的特征比较紧凑,关联也高,不解耦合的话模型很难学习到有用的东西),而w如何控制每一个渲染块呢,如下面公式所示:

每一个渲染块都有一个卷积核,w通过对卷积核进行仿射变换(按理说仿射变换是对数据进行缩放和平移操作的,style GAN就是这样,但是style GAN v2将平移给去掉了,只剩下缩放),其实就相当于变相地对特征图(每一层渲染块的输出,最开始是C1)进行仿射变换了,而这种仿射变换,在style GAN v2里面正是影响图像风格的关键因素。上面的公式,c代表卷积核的通道,i和j代表卷积核像素的坐标,整个分子是图中的Mod模块(调制,modulation),分母是图中的Dem模块(解调制,demodulation),其实可以理解为根据方差进行数据的归一化(毕竟训练神经网络一般也要进行batchnorm的嘛)其中的ϵ\epsilonϵ是为了防止除以0。
之后就是进行简单的卷积了,如下面公式所示:

之后该如何将法线贴图作用到我们的网络中呢,作者提出的NIM(法线注入)模块做的是下面的操作:

上面的fff是个三维的向量,nxyn_{xy}nxy​代表法线贴图(x,y)处的值,法线贴图的RGB通道就相当于该点法线的x,y,z值了,也是个三维向量,对应相乘,就完成所谓的法线注入了~

3.2 渲染器损失函数

了解了渲染器的结构,下面就来看看作者是如何设计损失函数的

3.2.1 法线一致性损失

我们在法线注入模块将法线贴图作用在了最终的输出,那么我们肯定希望法线贴图是对最终渲染图像的形状有影响,而不是其它方面,于是,我们让渲染出的图像的法线贴图与渲染输入的法线贴图两者尽量一致,这样就能让法线注入模块发挥控制渲染图像形状的作用了,于是有如下损失函数:

P可以看做是一个遮罩,遮挡不输入面部的区域,让它们别发挥作用,n是渲染器输入的法线贴图,N这里采用的是SFSNet,预测渲染图像的法线贴图。对应像素相乘,得到损失函数。

3.2.2 面部关键点一致性损失

在保证法线贴图对渲染图像的形状有影响之后还不够,因为还有latent code z控制着渲染图像的结果,我们希望让z别去控制形状,于是得考虑一种损失函数让二者解耦合,于是就有了下面的损失函数:

具体是什么原理呢,如果我让渲染器渲染两次,这两次的输入法线贴图是相同的,但是z不同,我们希望这两次输出的形状相同,其它方面不做追究,不就能够解决这个问题了吗。上面的G是渲染器,L是人脸关键点检测,用人脸关键点的距离来代替形状相似性的判断。

3.2.3 身份损失

有了上面的损失,看似就已经ok了,但是还不够,作者还在渲染出人物的身份性上做文章(类似于GANFIT),在法线贴图不同的时候,渲染出的人物可能是同一个人,可能是不同的人,具体是由其背后的3DMM系数与姿态系数(相机参数)控制的,于是为了让渲染器能够捕捉到法线贴图所蕴含的身份信息,提出了如下损失函数:

式子很简单,就是为了保证相同的形状α\alphaα与相同的z的前提下,对于不同的表情与拍摄角度,渲染器渲染出的是同一个人,其中的R是一个人脸识别网络

3.2.4 总的损失函数

如下图所示

其中的adv这个损失函数就是style GAN v2的损失函数

3.3 开始重建

当根据前面的损失函数与数据集训练好渲染器之后,我们就可以根据输入图像与渲染图像的像素差异进行三维重建了,具体损失如下所示:

可以看到优化的参数是这5个,与传统的三维重建相比,文章直接是用z来表示人脸纹理了,emmm确实有点抽象了。
重建的过程中,肯能需要对参数进行初始化的,那么是随机初始化吗?这样的话,作者根据《 Seeing what a gan cannot generate》 ICCV 2019 这篇深入分析GAN本质的文章,认为这样会陷入一种局部极小值,所以设计了一种反转的方式,去较好地初始化输入参数。
参数的初始化分为两部分,一部分是初始化z,通过设计了与渲染器对称的一种反转网络结构,用统计平均值和方差来估计z,如下式子所示:

其中为了估计初始输入,IoutI_{out}Iout​就给换成输入要准备重建的图像了,根据估计的初始输入再正向渲染一波,渲染图应该就和输入图像差个不离了。
另一部分参数的初始化就是3DMM系数了,直接用简单粗暴的传统方法:

具体可以看《A morphable model for the synthesis of 3d faces》这篇1999年的古董论文。

Inverting Generative Adversarial Renderer for Face Reconstruction相关推荐

  1. 论文笔记之:Generative Adversarial Text to Image Synthesis

    Generative Adversarial Text to Image Synthesis ICML 2016  摘要:本文将文本和图像练习起来,根据文本生成图像,结合 CNN 和 GAN 来有效的 ...

  2. DivCo: Diverse Conditional Image Synthesis via Contrastive Generative Adversarial Network

    模式崩溃是cGAN较为重要的问题,以往工作大多数都致力于关注latent code和生成图像之间的关系而没有关注通过不同latent code生成的图像之间的关系.MSGAN(mode seeking ...

  3. GAN(Generative Adversarial Nets)研究进展

    想与大家分享的是图像生成中一些工作. 这些工作都基于一大类模型,Generative Adversarial Networks(GAN).从模型名称上甚至都可以看出一些发展轨迹:GAN->CGA ...

  4. ESRGAN - Enhanced Super-Resolution Generative Adversarial Networks论文翻译——中英文对照

    文章作者:Tyan 博客:noahsnail.com  |  CSDN  |  简书 声明:作者翻译论文仅为学习,如有侵权请联系作者删除博文,谢谢! 翻译论文汇总:https://github.com ...

  5. Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network论文翻译——中英文对照

    文章作者:Tyan 博客:noahsnail.com  |  CSDN  |  简书 声明:作者翻译论文仅为学习,如有侵权请联系作者删除博文,谢谢! 翻译论文汇总:https://github.com ...

  6. 论文翻译:2019_Speech Super Resolution Generative Adversarial Network

    博客作者:凌逆战 论文地址:基于GAN的音频超分辨率 博客地址:https://www.cnblogs.com/LXP-Never/p/10874993.html 论文作者:Sefik Emre Es ...

  7. 论文翻译:Speech Super Resolution Generative Adversarial Network

    博客作者:凌逆战 论文地址:https://ieeexplore.ieee.org/document/8682215 博客地址:https://www.cnblogs.com/LXP-Never/p/ ...

  8. AniGAN: Style-Guided Generative Adversarial Networks for Unsupervised Anime Face Generation

    AniGAN: Style-Guided Generative Adversarial Networks for Unsupervised Anime Face Generation论文阅读 Gith ...

  9. MAD-GAN: Multivariate Anomaly Detection for Time Series Data with Generative Adversarial Networks

    MAD-GAN: Multivariate Anomaly Detection for Time Series Data with Generative Adversarial Networks 文章 ...

  10. Generative Adversarial Networks: An Overview文献阅读笔记

    Generative Adversarial Networks: An Overview笔记 Abstract Generative adversarial networks (GANs) provi ...

最新文章

  1. 使用sqlplus工具导出数据到csv文件,要求文件带有时间戳
  2. Vue里标签嵌套限制问题解决------解析DOM模板时注意事项:
  3. js导入导出总结与实践
  4. hihocoder 1343 : Stable Members【拓扑排序】
  5. c++ 数组的输入遇到特定字符停止输入_C语言 第4章-字符串和格式化输入/输出
  6. [react] 怎样在react中使用innerHTML?
  7. Golang实践录:命令行cobra库实例
  8. bfc是什么_清除浮动和 BFC
  9. 《南溪的目标检测学习笔记》——性能优化的学习笔记
  10. jmeter中变量的作用范围_Jmeter参数化方式总结
  11. Nginx配置共用80端口|端口转发端口映射
  12. 解决 IDEA 无法找到 java.util.Date 的问题
  13. 敌兵布阵 HDU 1166 线段树
  14. SwiftUI 设置圆角、边框
  15. 企业级Jumpserver的部署与使用-行癫亲测
  16. odoo 中的 domian 和 运算符
  17. 华为鸿蒙国内厂商适配,华为再放大招!鸿蒙系统将适配高通/联发科手机:获国产厂商力挺...
  18. 【Android】Studio 依赖 ButterKnife 黄油刀 时出现 空指针异常
  19. Word——删除最后一页空白页的方法
  20. 微信小程序开发—引用公共js里的方法

热门文章

  1. 2020博客之星结束了,感谢这些小伙伴们为我投票|博客之星TOP20的几位大佬
  2. 华为模拟器ensp下载地址
  3. 一卡通系统软件测试,智能一卡通管理系统检测流程
  4. 本地项目上传至git码云步骤(超详细,附图文)
  5. 仿微信读书APP原型设计
  6. 计算几何相关的面试题
  7. 基于WebUploader的文件上传插件
  8. 单片机驱动DM9000
  9. 74CMS的RCE挖掘思路
  10. r语言和python哪个难学_明明R语言比python容易学的多,为什么还有那么多人说R语言学起来陡峭?...