OSTeC: One-Shot Texture Completion

1. 相关工作

1.1 普通人脸图像的自动生成

  • 一般来说使用GAN,特别是styleGAN来生成人脸的图像,但是有个问题
  1. 人脸的特征难以解耦合:因为它的过程是参数—>参数空间—>图像,顶多来说,我们知道在低分辨率部分的参数控制着人脸的轮廓之类,高分辨率控制着人脸的具体细节,但是如果我想让侧着的人脸给正过来,就不知道该调节哪个部分比较好了
  2. 对于一张任意的野生图像,我也很难将其投射回styleGAN的原始参数空间
  • 因此,为了更好地控制GAN的生成,又有了许多image-image translation的GAN方法(估计和conditional GAN类似),这些方法的缺点便是训练的时候就是拿着成对的数据训练的,泛化性得不到有效保证

1.2 3D人脸纹理补全

  • 针对人脸三维重建的工作有很多,但是面临着的一个很大问题便是生成的人脸看起来不够真实,这种不真实的原因,当然渲染方式是一部分,但是最根本的原因是纹理方面的问题,因此也诞生了关于人脸三维纹理补全的工作,主要就是根据普通照片中人脸可见的部分补全人脸的纹理图

三维人脸的表示大致可以分为形状和纹理,对于真实感渲染来说,纹理是占重要比重的,哪怕形状再粗糙,只要纹理足够精细与逼真也能渲染出真实的人脸,那为了让纹理足够逼真(先不提分辨率的问题),至少GAN肯定是必不可少的了

  • 关于人脸纹理补全的举例:如下是用最简单的插值做的三维人脸纹理补全的方方法,首先根据人脸照片(第一张),根据某些工具(如dlib库)检测出的人脸landmark,使用优化的方式将人脸的网格(用3DMM系数表示)给贴到正好合适的位置(第二张),然后将这个网格的每个点赋予图像上的像素值,之后展开成平面,就得到了人脸的纹理图(第三张),这种方式当然简单方便,但是缺点便是我把三维人脸换个角度去看的话就出现了明显的拉伸条纹(artefacts)(第四张)
    在这里插入图片描述

  • 比如UV-GAN这篇文章就解决了三维人脸纹理补全的问题,如下图所示,问题就在于训练数据是人脸纹理图(人脸纹理图算是3D数据了)而不是自然的野生图像,导致泛化性得不到保证
    在这里插入图片描述

2. 本文方法

2.1 概述

总的来说,本文:

  1. 使用了基于优化的方式进行了三维人脸纹理补全,其中的先验用styleGAN存储
  2. 不需要使用三维数据进行训练,也就是说不需要人脸纹理图数据,仅仅使用野生的正常人脸数据训练即可

2.2 思路流程

  1. 我们的目标是要根据输入的人脸图像,生成人脸完整的纹理图,但是由于人脸纹理所包含的是三维信息,内容是比二维人脸图像丰富的,在输入的图像当中我们能看到的其实也只是纹理的一部分;而为了补全纹理缺失的部分,这些缺失部分就借助styleGAN里的信息来补全
  2. 既然一张图像无法填充完全纹理图,那我们可以考虑同一个人脸拍摄多个角度的照片来进行纹理图的填充,假设这些多个角度的照片都是真实而自然的话,我们通过某种方式把这些图片给缝补起来就能得到最终完整的人脸纹理图了,因此本文的框架也分为了两部分,一部分是如何仅仅根据一张输入的二维图像,得到若干张该人脸在不同摄像机角度下拍摄的足够真实的图片;另一部分是如何将这些足够真实的人脸图片给“缝补”成最终的完整的一张人脸纹理图
  3. 下面介绍一个基本的人脸到纹理的变换之后,先介绍下后部分的人脸纹理缝补,再介绍前部分的多角度真实人脸生成

2.3 用插值方式进行人脸到纹理&纹理到人脸的变换

在这里插入图片描述
以此图片为例,我们的目的是要从 I 0 I_0 I0得到 T 0 T_0 T0,也就是相当于把这张人脸的表皮给展开成一个平面,一个很自然的想法便是我先定义一个“一群锚点”到“另一群锚点”的变换,然后把这个变换给应用到 I 0 I_0 I0即可,而整个过程,可以用如下公式表示:
在这里插入图片描述
其中的 S ′ S' S就代表了这些“锚点”在图像的二维坐标, t c o o r d t_{coord} tcoord代表了这些点的纹理坐标,这两个量其实都可以由人脸三维重建里的3DMM系数轻易得到, t c o o r d t_{coord} tcoord本身是个固定的全局不变的量,而 S ′ S' S取决于相机的拍摄角度,整个公式可以这样理解:其中的 S ′ → t c o o r d S'\rightarrow t_{coord} Stcoord意味着 I 0 → T 0 I_0\rightarrow T_0 I0T0的规则,整个公式实现了图像到纹理的变换;而反过来同样的道理,我们要想实现纹理到图像的变换,把其中的参数换个位置即可
在这里插入图片描述
前面说了 S i ′ S'_i Si是取决于相机角度的,将角度的索引记为i(文章中用了6个相机角度,分别是原始输入的图像角度,底部,左底部,右底部,左侧,右侧) c i c_i ci就是相机参数,图像角度的相机参数是可以通过现成的成熟的人脸三维重建算法得到的,其它角度的相机参数都是固定值,下面的公式我们发现仅仅是将 t c o o r d t_{coord} tcoord S ′ S' S给换了个位置,就实现了纹理到图像的变换

2.4 人脸纹理缝补

这一步骤,主要的目标是根据文章方法得到的人脸不同角度的图像缝补成完整的人脸纹理图,如图所示:
在这里插入图片描述
自然,不同角度的人脸图像,肯定各自对于最终纹理图的某些区域贡献有大有小,首先为了评估这种贡献性大小,针对每个角度的图像,生成visibility score图,根据常理来说的话,人脸网格的三角形面法线与相机的距离向量夹角越小,其实就越意味着这部分区域对最终的纹理贡献大,visibility score图便是将不同角度下的人脸所对应的网格(由3DMM生成的那个)的每个点的属性看做是该点法向量与到相机的距离向量标准化之后的点积之后,再给渲染成纹理图的形式(根据2.3的式子)很显然,值越接近1的地方(越白),越意味着这片区域被摄像机照到,从而对最终的纹理图贡献越大,越黑(越接近-1)的地方越意味着获取不到这部分区域的信息,本文的6张visibility score图如下所示:
在这里插入图片描述
现在,我们有了6张不同角度的人脸真实图像(如流程图右部分所示),我们下一步先把他们各自展开成纹理图,对于各个角度的展开纹理图来说,必然地会在不同的地方产生条纹拉伸的效果,这些区域并不是我们想要的,而好在我们已经有了上面的6张visibility score,我们其实可以将其“拼接”成一个类似于“遮罩”的东西,称作visibility Index,如(h)图所示,每个颜色其实代表了各个角度的visibility score的索引,如中间的紫色区域意味着最终将这6张纹理图拼合成一张整个的纹理图示,这片区域应当使用(b)所对应的那张纹理图,蓝色区域表示应当使用(e)图所对应的那张纹理图,这样6张纹理图根据这一张visibility index图给各自提取出了相关区域,最终缝合,就得到了最终的完整不带条纹的人脸纹理图。

2.5 该如何从输入得到不同角度的真实人脸图呢?

讲完了后半部分,疑问自然就来到了这里:我这里的输入仅仅只有一张人脸正常图像,我该如何得到真实的不同角度的人脸图像呢?毕竟输入的图像可是个二维图像,我要是强行把它给换个角度,顶多会得到在2.3里面d图的效果,反正都有如此的条纹,我直接把原图给渲染成纹理图不就得了?然而这样其实相当于啥也没做啊!因此接下来的问题就变成了一个端到端图像转化的问题:
我该如何将一个带有条纹的某个角度的人脸图像,给变成一个不带条纹的相同角度下的人脸图像
解决了这一步,其实就大功告成了!如下图两个红框框里的转换一样,左边的红框框里面的人脸是有条纹的,右边的红框框里面的人脸是没有条纹的。
在这里插入图片描述
这就用到了styleGAN的架构,训练好之后,我们将其看做是一个解码器,按理来说,我们只要训练好一个编码器(style-Encoder)之后,把图像输入进去(因为图像是有着条纹的,为了不干扰结果,根据2.4为每个图像生成合适的遮罩,盖住有条纹的地方)之后,得到latent code,就能直接实现端到端转换了,但是作者觉得这样还不够,只是把现在的latent code当做了一个初始化的结果,之后继续使用基于优化的方法,来更精确地得到合适的latent code,具体而言,是分别使用了四个损失函数,来保证效果的良好,分别是Photometric loss,Identity Loss,Perceptual Loss,Landmark Loss,其实很容易理解,就不过多阐述了

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值