查看原文
其他

只要一张图片,秒变迪士尼角色!编程教学详解,你也能生成专属于你的迪士尼脸

21CTO 2021-10-21


上周我在网上冲浪时,偶然发现了贾斯汀·平克尼写的有关StyleGAN2 network blend的文章。 有人用文章中的想法制作了一个很酷的应用程序。多伦·阿德勒(Doron Adler)将StyleGAN2模型与迪士尼人物进行了微调,然后将图层与真实人脸模型(FFHQ)混合,生成了基于真实人脸的迪士尼人物。 
 
 

接着,贾斯汀·平克尼(Justin Pinkney)在 Toonify 上推出了这款模型。你只需上传你的照片,就能立即得到你的迪斯尼角色。试一下!
在这篇文章中,我们将学习如何通过编程来实现把人物动画化。 


目录

  • GAN
  • StyleGAN
  • 图层交换的Toonification
  • 通过一阶运动进行动画处理
  • 教程


GAN

角色生成背后的核心机制是一个被称为生成对抗网络(GAN)的概念,这款应用目前在网络中非常流行。什么是GAN?基本上是两个互相对抗的网络,即生成器和鉴别器。生成器试图欺骗鉴别器,使其相信生成的图像是真实的,而鉴别器则试图对真实图像和虚假(生成的)图像进行分类。
GAN 结构[来源: Generating Anime Characters with StyleGAN2 by Author] 
鉴别器将首先通过显示来自数据集的真实图像和随机噪声(来自未经训练的生成器的图像)来进行训练。由于数据分布差异较大,鉴别器可以很容易地进行鉴别。
初始鉴别器训练
然后,我们将切换到训练生成器,同时冻结鉴别器。生成器将学习如何产生更好的图像基于鉴别器的输出(真或假),直到鉴别器不能正确辨别。然后,我们切换回对鉴别器的训练,继续循环,两个鉴别器都变得越来越好,直到生成器能产生非常真实的图像,你就可以停止训练了。
 
GAN训练总结:生成器将学会生成更好的图像,鉴别器将学会更好地分类,因为假图像开始看起来非常相似。最终,在图像相似度上鉴别器只有一半的准确率。


StyleGAN

2018年,NVIDIA 发表了一篇突破性的论文,成功地生成了高质量的图像(1024x1024),题为《生成式敌对网络的基于风格的生成器架构》。论文的新颖之处在于,它可以消除潜在空间的纠缠,这使我们可以在不同的层次上控制属性。例如,较低的图层可以控制姿态和头部形状,而较高的图层可以控制较高层次的特征,如灯光或纹理。
通过引入一个附加的映射网络,将输入z(从正态分布采样的噪声/随机向量)映射到分离的向量w,并将其输入到不同的层中。因此,z输入的每个部分控制不同级别的特征。
因此,如果我们改变较低层(4x4, 8x8)的输入,之后将会在高层特征中有变化,比如头部形状,发型和姿势。
 
粗糙级别细节的变化(头部形状,发型,姿势,眼镜)
另一方面,如果您更改较高层次的输入(512x512、1024x1024),我们将有更好的特征(如灯光、肤色和头发颜色)上有所变化。
 精细级别细节的变化(头发颜色)
我们可以尝试通过分析激活映射并像本文所做的那样对激活进行集群,从而进一步可视化分离。
 使用球形K均值聚类的StyleGAN2,分析显示了StyleGAN语义解缠结。每种颜色代表不同的聚类
相同的颜色代表一个聚类 ,你可以把它看作是图像的可控部分。 在最后一层,你可以看到照明的不同部分被表示为不同的 聚类  在中间层,面部特征如眼睛、鼻子或嘴巴被表示为不同的 聚类 ,这意味着面部特征的变化在这是可控的。 最后,在最初的几层中,头部的不同部分被表示为不同的聚类 ,这证明了它控制着人的形状、姿势和发型。 
你可以在这里观看论文的演示视频。 

Editing in Style: Uncovering the Local Semantics of GANs - Crossminds


StyleGAN网络混合

StyleGAN独特的分离特征使我们能够混合不同的模型,并从一张脸生成迪士尼人物。前几个图层控制面部特征,最后几个图层控制纹理,如果我们用另一个模型的图层交换最后几个图层会怎样?
例如,我们在前几层使用脸部模型的权重,在剩下的层中使用绘画模型的权重,它将生成具有绘画风格的脸!不仅可以复制第二个模型的纹理,还可以复制不同模型的面部特征风格,比如迪斯尼人物的眼睛或者嘴巴。
 
FFHQ 模型和 Metface 模型之间的网络混合,在不同层和 16x16 层 |


一阶运动模型

在我们创造出迪士尼角色之后,为什么不把它提升到另一个层次,让它动起来呢?一篇题为“ 图像动画的一阶运动模型 ”的有趣的论文正好提供了我们这样做的能力。它学习运动从驾驶视频使用关键点,并试图变形输入图像,以制定运动。
一阶运动模型一览

 时装模特上的一阶运动模型。请注意,它能够为模型的背面制作动画。


教程

现在我们对这个概念有了一些了解,让我们用它编写代码吧。
首先,请确保你正在使用GPU运行时间,以及用Tensorflow 1。
% tensorflow_version 1.x
注意:%是Colab中的一个特殊命令,如果您在本地执行此操作,它将无法工作
接下来,我们克隆存储库并创建将要使用的文件夹。
!git clone %cd stylegan2!nvcc test_nvcc.cu -o test_nvcc -run!mkdir raw!mkdir aligned!mkdir generate
注意:”!'用于在Colab中运行shell命令,如果您在本地执行此操作,只需在您的shell/控制台上运行该命令。

接下来,将你的图像上传到原始文件夹中,我们将使用一个脚本来裁剪面部并调整图像大小,因此你的图像不必是全脸。为了得到更好的效果,请确保你的脸部至少有256x256的分辨率。
在这个例子中,我们将使用埃隆·马斯克的图像作为一个例子。
然后,我们将加载真实脸和迪士尼人物的混合模型,以及正常的FFHQ脸模型。
import pretrained_networks # use my copy of the blended model to save Doron's download bandwidth # get the original here https://mega.nz/folder/OtllzJwa#C947mCCdEfMCRTWnDcs4qw blended_url = "https://drive.google.com/uc?id=1H73TfV5gQ9ot7slSed_l-lim9X7pMRiU" ffhq_url = "http://d36zk2xti64re0.cloudfront.net/stylegan2/networks/stylegan2-ffhq-config-f.pkl" _, _, Gs_blended = pretrained_networks.load_networks(blended_url) _, _, Gs = pretrained_networks.load_networks(ffhq_url)
为什么还需要加载正常的真实面孔(FFHQ)模型?请记住,StyleGAN模型仅采用潜矢量z并基于潜矢量生成人脸。它不会像图像到图像转换模型那样拍摄图像并转换图像。
那么我们如何生成我们想要的脸呢?StyleGAN2介绍了一种投射到潜在空间的方法。一般我们可以尝试用梯度下降法,为我们想要的图像找到匹配的潜在向量。
在我们尝试找到匹配的潜在向量之前,我们需要先裁剪和对齐图像。
!python align_images.py raw aligned
该脚本将源图像目录和输出目录作为输入,并将剪裁和对齐我们的脸。

!python project_images.py --num-steps 500 aligned generated
该脚本将获取对齐目录中的图像,并在生成的文件夹中创建保存为.npy文件的潜在向量。

现在我们已经有了潜在的向量,我们可以尝试使用我们的混合迪斯尼模型来生成人脸。
import numpy as np from PIL import Image import dnnlib import dnnlib.tflib as tflib from pathlib import Path latent_dir = Path("generated") latents = latent_dir.glob("*.npy") for latent_file in latents: latent = np.load(latent_file) latent = np.expand_dims(latent,axis=0) synthesis_kwargs = dict(output_transform=dict(func=tflib.convert_images_to_uint8, nchw_to_nhwc=False), minibatch_size=8) images = Gs_blended.components.synthesis.run(latent, randomize_noise=False, **synthesis_kwargs) Image.fromarray(images.transpose((0,2,3,1))[0], 'RGB').save(latent_file.parent / (f"{latent_file.stem}-toon.jpg"))

生成的图像保存在生成的文件夹中。我们可以在笔记本里面显示图像。

from IPython.display import Image embedded = Image(filename="generated/example_01.png", width=256) display(embedded) tooned = Image(filename="generated/example_01-toon.jpg", width=256) display(tooned)


Elon Musk 卡通化
现在我们有了迪士尼化的埃隆·马斯克,但我们还没有结束。让它动起来吧!

首先,让我们将Aliaksanr的Repo复制到一阶模型上。
!git clone https://github.com/AliaksandrSiarohin/first-order-model

然后,我们将设置一个路径,这样我们就不必在一阶模型目录中用python导入,或者你

可以直接cd到该目录。

try: # set up path import sys sys.path.append('/content/stylegan2/first-order-model') print('Path added') except Exception as e: print(e) pass

然后,在我们加载关键点和视频生成器模型之前,我们需要先下载预先训练好的权重。这个文件相当大,约等于 700mb,你可能需要手动下载它,因为谷歌不允许wget下载大文件。

!wget "https://drive.google.com/uc?export=download&id=1jmcn19-c3p8mf39aYNXUhdMqzqDYZhQ_" -O vox-cpk.pth.tar


使用刚才下载的权重加载一阶模型。

from demo import load_checkpoints generator, kp_detector = load_checkpoints(config_path='first-order-model/config/vox-256.yaml', checkpoint_path='vox-cpk.pth.tar')


接下来,我们需要一个驱动视频,这个视频来自动画的来源。您可以使用示例视频或上传自己的视频。如果你上传了一个视频,请确保修改了相应的文件路径。

!wget https://drive.google.com/uc?id=1LjDoFmeP0hZQSsUmnou0UbQJJzQ8rMLR -O src_video.mp4
最后,我们可以生成动画了!
import imageio import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from skimage.transform import resize from IPython.display import HTML from demo import make_animation from skimage import img_as_ubyte import warnings warnings.filterwarnings("ignore") source_image = imageio.imread('generated/example_01-toon.jpg') reader = imageio.get_reader('src_video.mp4') #Resize image and video to 256x256 source_image = resize(source_image, (256, 256))[..., :3] fps = reader.get_meta_data()['fps'] driving_video = [] try: for im in reader: driving_video.append(im) except RuntimeError: pass reader.close() driving_video = [resize(frame, (256, 256))[..., :3] for frame in driving_video] # Generate animation predictions = make_animation(source_image, driving_video, generator, kp_detector, relative=True) def display(source, driving, generated=None): fig = plt.figure(figsize=(8 + 4 * (generated is not None), 6)) ims = [] for i in range(len(driving)): cols = [source] cols.append(driving[i]) if generated is not None: cols.append(generated[i]) im = plt.imshow(np.concatenate(cols, axis=1), animated=True) plt.axis('off') ims.append([im]) ani = animation.ArtistAnimation(fig, ims, interval=50, repeat_delay=1000) plt.close() return ani HTML(display(source_image, driving_video, predictions).to_html5_video())


我们终于做到了!如果你能做到这一点,祝贺你🎉


拓展

我们还可以做很多实验。如果我们混合其他的模型,如绘画的模型,或者我们也可以反向混合迪斯尼人物和绘画,产生一个基于迪士尼真实人物或绘画。我们也可以试着把Deepfake和迪士尼电影里的角色换脸。
来源:AI研习社译者:惠蕾_EvaHui


相关阅读:


亚马逊 CTO 回应人脸识别技术质疑:技术无罪,我们无责任

Google前CEO施密特:必须“不惜一切代价”在AI领域击败中国

张一鸣:用AI接管世界,全面发起海外战役


关于21CTO

21CTO.com是中国互联网第一技术社交与学习平台。为CTO、技术总监,技术专家,架构师、技术经理,高级研发工程师、PM等提供学习成长,教育培训,工作机会、人脉影响力等高价值的在线教育和社交网站。



: . Video Mini Program Like ,轻点两下取消赞 Wow ,轻点两下取消在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存