AI元宇宙敲门砖【2】:三维重建缔造虚拟形象

skyworking 镜像 如何搭建_paddlepaddle

引入

元宇宙、可微渲染、三维模型、Mesh的相关概念,在上一回已经讲过,忘记的同学可以去AI元宇宙敲门砖【1】:可微神经渲染助力虚拟物体创造项目里回顾一下。

FLAME:一个通过参数构造的人类头部三维Mesh模型生成器,可控制五官、表情、Pose等。

人脸三维模型重建:一个相当经典的图形学、计算机视觉任务,从一张或多张照片中重建人脸的三维模型。

为什么用三维建模而不是类似于stylegan之类的模型生成人脸?因为三维模型的解耦程度高且可供其它软件查看和使用。通过GAN生成的人脸则实际上没有所谓空间属性之类的东西,无法直接使用。

DECA: Detailed Expression Capture and Animation 简介

skyworking 镜像 如何搭建_计算机视觉_02

本项目使用的便是深度学习领域当前效果最好的三维人脸重建神经网络DECA,捕获单张图片中人像对应的纹理和表情,转换为与FLAME匹配的参数,通过调节FLAME参数实现重建出对应人像的三维模型,并且可以改变其姿态和表情。

而DECA训练的背后原理并不复杂:

  • 先使用人脸检测把照片中的人脸检测裁剪出来;
  • 通过Resnet提取人脸的特征并转为FLAME参数和纹理潜变量以及光照;
  • FLAME参数本身可微,并且可通过运算得到Mesh网格点;
  • 纹理潜变量通过可训练的生成器生成人脸的纹理;
  • 将网格点和纹理、光照输入可微渲染器进行光栅化,最后渲染得到人脸图片;
  • 将这张渲染图和原人脸图像做loss计算,由优化器改变参数降低loss实现端到端的训练。

本项目实现细节

由于原项目使用到了相当多的算子组合来实现一些网格运算的算子,过于复杂。为了避免头秃(在已经头秃几日后),笔者选择将模型的一部分转换为onnx,简单的部分以及涉及到c++的部分手写paddle。

本来想转成onnx后通过x2paddle再将onnx转到paddle中的,结果x2paddle对onnx的支持只含版本9。笔者只能退而取其次,用onnxruntime直接运行网络的一部分,剩下部分再交予paddle来完成。

所以本项目相当于只提供了一个推理接口,并不能进行训练。不过给大家体验一下元宇宙可能会运用的技术应该也是足够了。

实现

如果大家觉得不错的话,记得给笔者的Github项目DECA-Paddle-Inference点个星星哦。

动手体验

准备代码与运行环境

运行AI Studio的GPU环境,安装笔者预先准备好的包文件,完成环境配置。

# 安装运行环境并将预训练模型复制到指定位置
%pip install ppgan data/data127751/onnxruntime_gpu-1.10.0-cp37-cp37m-linux_x86_64.whl
!mkdir -p DECA-Paddle-Inference/TestSamples/examples/results/
!rm -rf DECA-Paddle-Inference/TestSamples/examples/results/*
!ln -sf /home/aistudio/data/data127751/deca_encoder.onnx /home/aistudio/DECA-Paddle-Inference/TestSamples/examples/results/deca_encoder.onnx
!ln -sf /home/aistudio/data/data127751/deca_decoder.onnx /home/aistudio/DECA-Paddle-Inference/TestSamples/examples/results/deca_decoder.onnx

重建示例图片为三维人脸模型

经过模型运算可得到示例图片的重建三维模型以及渲染结果的图片

# 重建TestSamples/examples目录下的人脸照片,生成结果到TestSamples/examples/results下
!cd DECA-Paddle-Inference && python reconstruct.py -i TestSamples/examples --useTex True --saveObj True --saveImages True
from IPython.display import display, Image

# 查看原始输入
print('要重建的人脸:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/id04657-PPHljWCZ53c-000565_inputs_inputs/id04657-PPHljWCZ53c-000565_inputs_inputs_images.jpg'))

# 查看重建结果
print('重建人脸的渲染结果:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/id04657-PPHljWCZ53c-000565_inputs_inputs/id04657-PPHljWCZ53c-000565_inputs_inputs_rendered_images.jpg'))

# 模型的UV贴图
print('重建人脸三维模型的UV贴图:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/id04657-PPHljWCZ53c-000565_inputs_inputs/id04657-PPHljWCZ53c-000565_inputs_inputs.png'))
要重建的人脸:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Y9rB4uI-1645273166969)(output_7_1.jpg)]

重建人脸的渲染结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CSwNx2c4-1645273166970)(output_7_3.jpg)]

重建人脸三维模型的UV贴图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lZQf9gpO-1645273166970)(output_7_5.png)]

通过观察UV贴图可以注意到,模型其实还是不能处理看不到的地方的纹理以及多余的头发纹理的。不过对人脸的还原还是比较到位的。

下载整个文件夹,可通过windows 10自带的3d查看器查看模型(.obj格式)

skyworking 镜像 如何搭建_paddlepaddle_03

将重建人脸的表情从另一个人脸上迁移过来

重建过程中产生的FLAME参数包含有姿态和表情,那么替换为他者的参数,便可以实现表情迁移啦。

# 重建TestSamples/examples目录下的王冰冰人脸照片和某示例人脸,
# 并将示例人脸的表情迁移到王冰冰的重建人脸上。
# 生成结果到TestSamples/examples/results下
!cd DECA-Paddle-Inference && python transfer.py --useTex True --saveObj True --saveImages True \
  -i TestSamples/examples/bingbingwang.jpg -e TestSamples/examples/image02673.png
from IPython.display import display, Image

# 查看原始输入
print('要重建的人脸:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/bingbingwang/bingbingwang_images.jpg'))

# 查看重建结果
print('重建人脸的渲染结果:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/bingbingwang/bingbingwang_rendered_images.jpg'))

# 表情来源
print('迁移表情的来源:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/image02673/image02673_images.jpg'))

# 查看重建结果
print('迁移表情后人脸的渲染结果:')
display(Image('DECA-Paddle-Inference/TestSamples/examples/results/bingbingwang_exp_from_image02673/bingbingwang_exp_from_image02673_rendered_images.jpg'))
要重建的人脸:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5L2ohVTU-1645273166971)(output_11_1.jpg)]

重建人脸的渲染结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iGKoD2vg-1645273166971)(output_11_3.jpg)]

迁移表情的来源:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BYQ28F43-1645273166972)(output_11_5.jpg)]

迁移表情后人脸的渲染结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sNBYPRXe-1645273166972)(output_11_7.jpg)]

源模型查看

skyworking 镜像 如何搭建_paddlepaddle

表情迁移模型查看

skyworking 镜像 如何搭建_skyworking 镜像 如何搭建_05

结语

哈哈哈,结果还是有些看不过去。瞪大眼睛的表情似乎也没有迁移成功

不过对于单张图片重建人脸,其实效果还可以。若是要达到影视效果那种精度的人脸模型,恐怕需要不少特殊设备以及完全不同的算法。

期待未来有更加厉害的模型可供使用。