用 TensorFlow.js 让蒙娜丽莎效应栩栩如生
2020 年 9 月 25 日

来自 Emily Xie 的客座文章,软件工程师

背景

传说蒙娜丽莎的眼睛会随着你移动而移动,这就是所谓的“蒙娜丽莎效应”。为了好玩,我最近编写了一个 交互式数字肖像,通过你的浏览器和网络摄像头将这种现象带入生活。

该项目的核心利用了 TensorFlow.js、深度学习和一些图像处理技术。总体思路如下:首先,我们必须生成蒙娜丽莎头部的一系列图像,眼睛从左到右凝视。从这个池中,我们将根据观察者的位置实时连续选择并显示单个帧。

在这篇文章中,我将详细介绍该项目的技术设计和实现细节。

用深度学习动画化蒙娜丽莎

图像动画是一种技术,它允许人们通过驱动视频来操控静止图像。使用基于深度学习的方法,我能够生成蒙娜丽莎凝视的高度逼真的动画。

具体来说,我使用了 Aliaksandr Siarohin 等人于 2019 年发布的 一阶运动模型 (FOMM)。在非常高的层面上,这种方法由两个模块组成:一个用于运动提取,另一个用于图像生成。运动模块检测驱动视频中的关键点和局部 仿射变换。然后,将这些值在连续帧之间的差值用作网络的输入,该网络预测密集的 运动场,以及一个遮挡掩码,该掩码指定需要修改或上下文推断的图像区域。然后,图像生成网络检测面部特征点并生成最终输出——根据运动模块的结果扭曲和修复的源图像。

我之所以选择 FOMM,是因为它易于使用。该领域之前的模型都是“特定于对象的”,这意味着它们需要被动画对象的详细数据,而 FOMM 则与之无关。更重要的是,作者发布了一个开源的、开箱即用的实现,其中包含用于面部动画的预训练权重。因此,将该模型应用于蒙娜丽莎变得出奇地简单:我只是将代码库克隆到一个 Colab 笔记本中,生成一个我眼睛四处移动的简短驱动视频,并将其与 La Gioconda 的头部截图一起输入模型。最终的电影效果很棒。最终,我从这些电影中采样了 33 张图像来构成最终的动画。

驱动视频和 FOMM 生成的图像动画预测的示例。
使用一阶运动模型生成的最终动画帧的子样本。

图像混合

虽然我可以重新训练该模型以用于我的项目目的,但我决定在 Siarohin 的权重的限制范围内工作,以避免否则需要的時間和计算资源。然而,这意味着生成的帧的分辨率低于预期,并且只包含主题的头部。但由于我希望最终视觉效果包含蒙娜丽莎的全部——包括手、躯干和背景——我的计划是简单地将输出头部帧叠加在绘画的图像上。

Mona Lisa
头部帧叠加在底层图像上的示例。为了更好地说明问题,此处显示的版本来自项目的早期迭代,其中头部帧存在进一步的分辨率损失。

然而,这带来了自己的挑战。如果你看一下上面的例子,你会注意到,模型的低分辨率输出——再加上由于 FOMM 的扭曲过程导致的一些微妙的背景变化——会导致头部帧在视觉上突出。换句话说,很明显这只是一张图片叠加在另一张图片上。为了解决这个问题,我在 Python 中进行了一些图像处理,以将头部图像“混合”到底层图像中。

首先,我将头部帧调整到其原始分辨率。从那里,我使用这些模糊像素和底层图像中对应像素的加权平均值创建了一个新帧,其中头部帧中像素的权重——或 alpha——随着它远离中点而减小。

确定 alpha 的函数改编自 2D sigmoid,表示为

其中 j 决定逻辑函数的斜率,k 是拐点,m 是输入值的中间点。绘制出来,该函数看起来像

Function graph

在将上述过程应用于动画集中所有 33 帧后,最终的叠加效果看起来都像是对毫无戒备的眼睛来说的单张图像

通过 BlazeFace 跟踪观察者的头部

现在剩下要做的就是确定如何通过网络摄像头跟踪用户并显示相应的帧。

自然地,我转向 TensorFlow.js 来完成这项工作。该库提供了一套相当强大的模型来检测给定视觉输入的人类存在,但经过一番研究和思考,我最终选择了 BlazeFace 作为我的选择方法。

BlazeFace 是一种基于深度学习的对象识别模型,它检测人脸和面部特征点。它专门针对使用移动摄像机输入进行训练。这对于我的用例非常有效,因为我预计大多数观众都会以类似的方式使用他们的网络摄像头——他们的头部在画面中,正面朝向,并且相当靠近相机——无论他们使用的是移动设备还是笔记本电脑。

然而,我选择这个模型的最重要考虑因素是它的惊人检测速度。为了使这个项目令人信服,我需要能够实时运行整个动画,包括面部识别步骤。BlazeFace 采用单次检测 (SSD) 模型,这是一种基于深度学习的对象检测算法,它仅通过网络的一次前向传递即可同时提出边界框并检测对象。BlazeFace 的轻量级检测器能够以高达每秒 200 帧的速度识别面部特征点。

BlazeFace 在给定输入图像的情况下可以捕获的内容演示:人头的边界框以及面部特征点。

确定了模型后,我编写了代码来将用户的网络摄像头数据不断地传送到 BlazeFace。在每次运行时,该模型都会输出面部特征点及其对应二维坐标位置的数组。使用它,我通过计算眼睛之间的中点来近似地确定脸部中心的 X 坐标。

最后,我将此结果映射到 0 到 32 之间的整数。正如你可能记得,这些值分别代表动画序列中的一个帧——其中 0 表示蒙娜丽莎的眼睛朝左,32 表示她的眼睛朝右。从那里,只需要在屏幕上显示帧即可。

试试吧!

你可以在 monalisaeffect.com 上体验该项目。要了解更多我的作品,请随时访问我的个人 网站GithubTwitter

鸣谢

感谢 Andrew Fu 阅读这篇文章并给我提供反馈,感谢 Nick Platt 倾听我关于前端错误的思考,感谢 Jason Mayes 以及 Google 团队其他成员的努力,他们伸出援手,宣传了这个项目。

下一篇文章
 Bringing the Mona Lisa Effect to Life with TensorFlow.js

来自 Emily Xie 的客座文章,软件工程师背景传说蒙娜丽莎的眼睛会随着你移动而移动,这就是所谓的“蒙娜丽莎效应”。为了好玩,我最近编写了一个 交互式数字肖像,通过你的浏览器和网络摄像头将这种现象带入生活。该项目的核心利用了 TensorFlow.js、深度学习和一些图像处理技术。总体思路如下:首先,我们必须生成蒙娜丽莎头部的一系列图像,眼睛从左到右凝视。从这个池中,我们将根据观察者的位置实时连续选择并显示单个帧。