3DCaricShop指的是文章提出的一种数据集,而这篇文章是关于二维讽刺漫画(标题里是caricture,个人觉得翻译成讽刺漫画更加合适)的单视图三维重建。关于单视图三维人脸重建的研究有很多,这篇文章算是在这个领域的一个更小的分支(讽刺漫画人脸)做出了一些工作,可以主要概括为如下几点:
基于2D卡通图像(后面就统一将caricture翻译成卡通了,但是记住这篇文章做的工作主要指的是卡通讽刺漫画)重建3D卡通的工作比较稀少,《Alive caricature from 2d to 3d》(CVPR2018)这篇文章首先提出了一种基于优化的方法,将其看做是一种标准3D脸的变形(类似于3DMM系数),但是3DMM的方法早就被证明了有着一定的局限性,因为其实本质上可以看做一系列脸的线性叠加,更何况这种卡通脸比正常人脸有着更复杂的表情。为了解决这个问题,需要高质量的3D卡通数据集来提供形状先验,不管是基于学习的方法还是基于优化的方法。但是有两个挑战性的问题:
面对以上3D卡通数据集在构建过程中可能出现的问题,本文提出的3DCaricShop成功解决了。
单目重建大致分为普通物体三维重建与特定物体三维重建(如人脸),《Shape from shading》这篇文章分析了光照与形状的关系,能够覆盖照片中形状的小细节,但是当分析卡通人物的时候失效,因为卡通的光影比较特殊。在3D重建的时候,方法大致可以分为体素表示、点云表示、网格表示、隐函数表示,而基于深度隐函数的方法,有《Deep volumetric video from very sparse multi-view perfor
mance capture》(ECCV2018),《Deepsdf: Learning continuous signed distance functions for shape representation》(CVPR2019)这两篇文章,证明表示任意拓扑结构展现了一定的能力,于是本文主要也采用了隐函数方法实现三维重建。
虽然使用隐函数的方法能够保证精确性,但是毕竟是隐函数,无法直接给变成网格表示,于是本文就想用一种参数化的方式(类似于3DMM系数)来根据隐函数表示重建的三维卡通人脸。但是又有问题了,虽然使用参数化网格模型的方法可以确保生成可信的3D人脸,但它们难以生成具有精确几何形状的真实人脸。也就是说,我用的是PCA方法,但是我得尽量让他更加精确,于是本文主张通过将隐式重建学到的高保真几何转移到一个具有合理拓扑结构的模板网格中来结合两种方法的好处。(emmm继续往后看文章吧,看完再来品味这句话)
为了确保可靠的转换,本文提出了一种新的视图协同图卷积网络(VC-GCN)从隐式网格中提取关键点,实现精确的网格对齐。为了在准确性和鲁棒性之间取得平衡,使用3DCaricShop迭代地将注册模板网格投影到预训练的PCA空间上,以避免对异常值的过拟合。(这句话概括的实在是太抽象了,还是继续往后看具体方法吧)
本文首先从WebCaricature这个数据集里抽出2000张卡通的2D图像,然后雇佣了4个艺术家创作其对应的三维模型,尽量保持投影一致。当然得到的模型网格肯定是五花八门的,之后为了解决网格统一的问题,首先对于每个模型手工标注了44个3D关键点,之后由这些标注的3D关键点作为引导使用非刚性配准(NICP)将一个预定义好的模型(11551个顶点)与模型匹配。并且标注的时候还不是直接取mesh的顶点,而是使用三个渲染视图进行标注(因为有可能关键点不会恰好落在网格顶点上),不过要让他恢复到三维空间中自有办法。
如图所示是本文的数据集处理过程:
a:艺术家手工建模的原始三维模型渲染图
b:分别从三个渲染视图进行关键点的手工标注
d:当标注后通过某种方法将其转换到三维的全局坐标(将三维的网格投影到相应的视图,寻找最近的标注点,那么这个标注点的三维坐标其实就得到了)
e:准备进行非刚性配准的模板人脸网格,上面已经有预先定义好的关键点了
c:用这些关键点进行模板网络的变形,得到统一拓扑结构的人脸三维模型
给我们一张2D的卡通图像,我们的目的是生成对应的三维网格(本文没有提纹理相关的方法,主要工作都是进行形状的三维重建)。现在有了3DCaricShop这样的一个数据集,当然可以模仿BFM数据集一样使用PCA的方法来将重建的三维人脸用一系列PCA系数进行表示,但是考虑到这些卡通人脸模型的姿态比较夸张,于是没有选择直接用优化的方法来进行三维重建,而是先用《Pifu: Pixel-aligned implicit function for high-resolution clothed human digitization》(ICCV2019)这篇论文里的方法进行隐式的三维重建,之后再用一个预定义好的模板进行非刚性配准,得到一个统一的三维网格模型,之后再进行PCA投影得到三维模型的系数表示。
在非刚性配准的过程中,可能会出现一些变形的现象,如自交(self-intersection,个人理解就是网格曲面弯曲过大,以至于自己与自己进行了相交),于是在这之前进行了44个关键点的预测,用这些关键点引导配准以减轻这种自交现象,当然这44个关键点的预测过程也并不简单,采用了一种“视图协同图卷积网络”的方式。
整个流程如下图所示,之后分四个小部分逐一介绍
假设给我们p个卡通的三维模型,每个模型有N个顶点,用PCA方法,一方面可以生成一系列的特征向量作为基底,一方面生成平均模型,之后任给一个模型 S N S_N SN,可以用如下公式进行表示:
其中
这样给我一个数据集,给我一个数据集之外的三维模型,我就可以用一系列系数a来表示这个三维模型了。1999年的3DMM模型核心方法就是这种PCA方法,使用的数据集是BFM数据集,本文也是采用的这种方法,只不过数据集换成了自己造的3DCaricShop。
因为卡通三维重建的姿态较为夸张,于是选择PIFu这种隐式的方法进行三维重建,以便于捕捉更多的细节,而这种方法具体是什么呢,如下公式所示:
用上面这样一个隐函数,来表示三维模型,其中函数的输入依次为:
下面来具体分析下为什么上面的隐函数能够表示一张图像的三维模型:
假设我们有了这样的一个重建好的三维模型,就用上面的隐函数来进行表示,那么我可以随便说一个三维坐标X,让这个隐函数来判断这个X是在三维模型的里面还是外面,如果是里面输出为1,如果是外面输出为0,这个隐函数其实是一个神经网络,输出当然是一个在0-1连续的值,不过这无所谓,我们就直接判断[0,0.5]区间的值为0,判断[0.5,1]区间的值为1即可。只要我的点取的足够多,那么通过这个隐函数我们是能够推测出这个三维模型具体是什么样子的,这也是为什么上面的式子能够表示三维模型的原因。事实上,这个隐函数神经网络应该是个多层感知机,是线性的,没有激活函数,于是我们如果把结果直接设置为0.5,就可以反过来得出这个三维模型的表面。
下面再说训练过程。如下公式所示:
对于数据集的每一个样本索引 i i i,其中的二维图像 I i I_i Ii,我们先用GAN《High-resolution image synthesis and semantic manipulation with conditional gans》(CVPR2018)生成两张法线贴图,得到 F i F_i Fi和 B i B_i Bi,之后取几个采样点(暂时没看PIFu这篇论文,这里推测X应该是个矩阵,对应着许多采样点,不然的话每个样本只有一个采样点感觉不太合理),每个采样点根据样本的三维模型,都是有确定位置的,所以要么为0要么为1,用后面的 f ∗ ( X i ) f^*(X_i) f∗(Xi)表示,对应这个隐函数神经网络期望的输出。而通过优化上面的损失函数,来训练得到最终的隐函数的神经网络。
首先本文先搞出了一个模板网格,作为本文方法进行三维重建的统一模板,并且这个网格能够进行3DCaricShop这个数据集的PCA投影,无论将来这个模板网格的形状怎么变,都能得到对应的PCA系数。之后根据隐式重建的三维模型,将这个模板网格不断地变形以慢慢地匹配(这应该就是所说的非刚性配准),但是直接进行这样的配准文中说会陷入局部最小值,整个模板会
塌陷在这个隐函数的表面,于是引入了3D关键点来辅助变形。具体是怎么引入3D关键点的呢,用了后文要说的VC-GCN。
有了关键点之后,还是得考虑隐函数模型与模板模型的巨大差异性,如果直接进行配准可能会导致自交现象,为了解决这个问题,只好慢慢来,先稍微配准一下,让模板进行细微的变形,然后进行PCA投影,保证稳定性,得到一种处于初始的模板模型与隐函数模型之间的一种过渡状态模型,然后这样迭代慢慢地逼近最终的隐函数模型。
这一部分的主要目的是如何根据已有的隐函数模型,去预测44个关键点,好为将来的模型配准做准备。流程图如下所示
对于隐函数三维模型,首先根据左面,正面,右面三个方向,得到渲染图,之后根据 《Pfld: A practical facial landmark detector》(CVPR2019)提出的2D关键点检测的方法,去预测每一个渲染视图的关键点的2D坐标,之后根据投影矩阵,得到每个视图里的关键点的3D局部坐标(其实就是各自的相机坐标)
然后,为了丰富每个图节点的信息,从每个节点的检测器生成的特征图中,根据其2D坐标提取特征,之后将每个关键点的三维坐标与这些特征的维度拼接起来得到图网络的输入。如果特征图里每个关键点的特征是C个的话,在进行图卷积之前,每个关键点的特征共为C+3个。记为:
这里的F表示的就是图卷积网络的每个节点的特征矩阵,上标v代表左面、正面、右面渲染视图中的某一个, k v k^v kv代表视图v检测出的关键点数量,每个视图检测出的关键点因为遮挡的问题,数量肯定是不一样的。
对于每个渲染视图节点进行初始化之后,得到的是三个视图的局部特征,这些关键点都是局部的三维坐标,而最终我们将要通过GCN来得到关键点的世界坐标。
接下来,将这些局部特征分别放入三个图卷积网络中,公式如下所示:
l代表图卷积网络的每一层, σ \sigma σ代表激活函数, A v A^v Av是邻接矩阵, D v − 1 / 2 A v D v − 1 / 2 D^{v-1/2}A^vD^{v-1/2} Dv−1/2AvDv−1/2可以理解为进行归一化操作, F l v F^v_l Flv就是每个视图在第l层的局部特征, W l W_l Wl就是要训练的图卷积网络的参数。
经过若干层之后,将这三个视图进行合并操作,得到全局图的特征:
得到全局特征之后并没有这么轻易地结束,作者认为全局特征还能够进一步引导模型学习局部的一些特征,于是采用了一种非局部(non-local)的方式,将局部特征进行了增强,这样又得到了之前的三个视图的局部特征:
这样就又回到了图卷积网络的初始位置,这个过程循环进行,得到最终的输出。
至于损失函数,如下所示:
其中P是关键点2D坐标,L是关键点三维坐标,第一项代表2D关键点检测的损失函数,第二项代表预测的关键点三维坐标之间的损失,第三项代表我将预测到的三维坐标按照投影矩阵映射到二维坐标与之比较得到的损失,这三项之间的比重为0.1:0.8:0.1。
在自己造的3DCaricShop数据集上的效果
与其它方法的比较
消融实验1:
消融实验2: