摘要:本文将介绍如何借力一站式 AI 开发平台,“傻瓜式”操作实现生成“蚂蚁牙黑“小视频。
作者:华为云EI专家胡琦
一夜之间,朋友圈都在“蚂蚁牙黑”!网友却担心......"Baby, don't worry, we have ModelArts!",是的,咱用 ModelArts 来制作,无需担心“有人模仿我的脸?”,也不用担心偌大的水印。不过,使用别人的脸可能真的有法律风险!本文将介绍如何借力一站式 AI 开发平台,“傻瓜式”操作实现生成“蚂蚁牙黑“小视频。
环境准备
ModelArts 和她的最佳搭档--对象存储服务 OBS ,您可以理解为是“网盘”,主要要来存放数据集、模型或其他文件。
ModelArts: https://www.huaweicloud.com/product/modelarts.html AI开发平台ModelArts是面向开发者的一站式AI开发平台,为机器学习与深度学习提供海量数据预处理及半自动化标注、大规模分布式Training、自动化模型生成,及端-边-云模型按需部署能力,帮助用户快速创建和部署模型,管理全周期AI工作流。
OBS: https://www.huaweicloud.com/product/obs.html
对象存储服务(Object Storage Service,OBS)提供海量、安全、高可靠、低成本的数据存储能力,可供用户存储任意类型和大小的数据。适合企业备份/归档、视频点播、视频监控等多种数据存储场景。
使用以上服务会有一定费用产生,或者您可以尝试认证为开发者会有一定代金券赠送,当然关注 ModelArts 和加入 ModelArts 开发者社区也会有机会获得大额代金券。
模型、素材准备
本次实现使用的是用于图像动画的一阶运动模型,这是一种基于关键点和局部仿射变换的图像动画方法,
论文地址:https://arxiv.org/abs/2003.00196
下载预训练模型及素材
最近手头紧,非常抱歉不能为大家提供 OBS 路径直接下载,我已将预训练模型及素材上传到 AI Gallery 数据集,请自行下载到您的 OBS 中。当然如果您有可快速下载的地址,欢迎分享!
源文件地址:https://drive.google.com/drive/folders/1kZ1gCnpfU0BnpdU47pLM_TQ6RypDDqgw?usp=sharing 或者https://drive.google.com/drive/folders/16inDpBRPT1UC0YMGMX3dKvRnOUsf5Dhn?usp=sharing 因为是源文件,因此不包含”蚂蚁牙黑“原视频素材,但我已添加至AI Gallery 数据集。如仍有需求,可以直接找我要,公众号:胡琦,WeChat:Hugi66;欢迎加入 ModelArts 开发者社区,广州地区的小伙伴可以加入我们共创 MDG 广州站哦!
AI Gallery 是在 ModelArts 的基础上构建的开发者生态社区,提供模型、算法、HiLens技能、数据集等内容的共享和交易。因此您可以下载分发的数据集或文件到您的 OBS ,使用时请遵守相应的政策和规则!打开 https://marketplace.huaweicloud.com/markets/aihub/datasets/detail/?content_id=00bc20c3-2a00-4231-bdfd-dfa3eb62a46d 点击下载按钮进入下载详情,设置 OBS 路径,确定下载即可将模型和素材下载到自己的 OBS 中,比如我路径是/modelarts-lab/first-order-motion-model。下载进度可以在 AI Gallery 个人中心-我的下载查看。
JUST DO IT -- ModelArts 我的笔记本
接下来开始使用 ModelArts--我的笔记本 ,即开即用的在线集成开发环境,可以轻松的构建、训练、调试、部署机器学习算法与模型。当前使用免费规格用于体验, 值得留意的是 72 小时内没有使用,会释放资源,因此需要注意文件备份。当然还可以使用 Notebook 免费算力,记得选择 GPU 环境哦!
当我们使用我的笔记本时默认开启的是 CPU 环境,因此我们需要切换到 GPU 环境。目前 ModelArts-我的笔记本 支持8 vCPU + 64 GiB + 1 x Tesla V100-PCIE-32GB。
新建Pytorch 1.0的.ipynb文件,开始我们的“蚂蚁呀嘿”体验之旅。
下载代码
-
!git
clone https:
//github.com/AliaksandrSiarohin/first-order-model
-
# or
-
!git
clone https:
//codehub.devcloud.cn-north-4.huaweicloud.com/ai-pome-free00001/first-order-model.git
github 速度慢,建议转存到华为云代码托管平台再拉取。
此处提供我已经缓存好的代码仓库地址,因此不再演示如何将 github 代码迁移到 codehub。(不保证我的账号欠费而无法访问,因此建议大家以自己的方式上传代码到 Notebook !)
利用 Moxing 拷贝文件到 JupyterLab,将之前下载到 OBS 中的模型和素材通过 Moxing 拷贝过来,此处注意替换为您的 OBS 路径。02.mp4是“蚂蚁呀嘿”的模版视频,
-
# 此处牛刀小试--用 Moxing 下载文件
-
import moxing as mox
-
# 此处需要替换您的 OBS 地址
-
mox.file.copy_parallel('obs://modelarts-lab/first-order-motion-model/first-order-motion-model-
20210226T
075740Z-
001.zip' , 'first-order-motion-model.zip')
-
mox.file.copy_parallel('obs://modelarts-lab/first-order-motion-model/
02.mp
4' , '
02.mp
4')
-
# 解压
-
!unzip
first-order-motion-model.zip
-
# 模版视频
-
!mv
02.
mp4
first-order-motion-model/
准备工作完成之后,撸起袖子就是干!切换到first-order-model目录,然后将 source_image_path中的路径替换为”您的脸”所在的路径,脸的照片可以直接通过 Notebook 的文件上传功能上传。当然您还可以将默认的“蚂蚁牙黑”视频替换为您自定义的视频,格式为 mp4。一路执行可以查看到合成前的预览。
-
cd first-order-model
-
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
-
import warnings
-
warnings.filterwarnings(
"ignore")
-
-
# 此处替换为您的图片路径,图片最好为 256*256,这里默认为普京大帝
-
source_image_path =
'/home/ma-user/work/first-order-motion-model/02.png'
-
source_image = imageio.imread(source_image_path)
-
-
# 此处可替换为您的视频路径,这里默认为“蚂蚁牙黑”
-
reader_path =
'/home/ma-user/work/first-order-motion-model/02.mp4'
-
reader = imageio.get_reader(reader_path)
-
# 调整图片和视频大小为 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]
-
-
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).to_html5_video())
这一步完成之后,我们便得到了“蚂蚁呀嘿”的视频了--“generated.mp4”,这就结束了?不过,问题来了……
-
from demo import load_checkpoints
-
generator, kp_detector = load_checkpoints(config_path=
'config/vox-256.yaml',
-
checkpoint_path=
'/home/ma-user/work/first-order-motion-model/vox-cpk.pth.tar')
-
from demo
import make_animation
-
from skimage
import img_as_ubyte
-
-
predictions = make_animation(source_image, driving_video, generator, kp_detector, relative=
True)
-
-
# 保存结果视频
-
imageio.mimsave(
'../generated.mp4', [img_as_ubyte(frame)
for frame
in predictions], fps=fps)
-
# 在 Notebook 根目录能找,/home/ma-user/work/
-
-
HTML(display(source_image, driving_video, predictions).to_html5_video())
如果您和我一样直接下载并打开上面操作的产物--generated.mp4,您一定会和我一样困惑:声音呢?是的,声音丢失了,因为核心代码只处理图像,声音需要我们自行找回,因为我们使用moviepy。不仅如此,我们还可以为视频加水印。
-
# 安装视频剪辑神器 moviepy
-
!pip
install moviepy
-
# 为生成的视频加上源视频声音
-
from moviepy.editor import *
-
-
videoclip_1 = VideoFileClip(reader_path)
-
videoclip_2 = VideoFileClip(
"../generated.mp4")
-
-
audio_1 = videoclip_1.audio
-
-
videoclip_3 = videoclip_2.set_audio(audio_1)
-
-
videoclip_3.write_videofile(
"../result.mp4", audio_codec=
"aac")
-
# 还可以给视频加水印
-
video = VideoFileClip(
"../result.mp4")
-
# 水印图片请自行上传
-
logo = (ImageClip(
"/home/ma-user/work/first-order-motion-model/water.png")
-
.set_duration(video.duration)
# 水印持续时间
-
.resize(height=50)
# 水印的高度,会等比缩放
-
.margin(right=0, top=0, opacity=1)
# 水印边距和透明度
-
.set_pos((
"left",
"top")))
# 水印的位置
-
-
final = CompositeVideoClip([video, logo])
-
final.write_videofile(
"../result_water.mp4", audio_codec=
"aac")
-
-
final_reader = imageio.get_reader(
"../result_water.mp4")
-
-
fps = final_reader.get_meta_data()['fps']
-
result_water_video = []
-
try:
-
for im in final_reader:
-
result_water_video.append(im)
-
except RuntimeError:
-
pass
-
reader.close()
-
result_water_video = [resize(frame, (256, 256))[..., :3] for frame in result_water_video]
-
HTML(display(source_image, driving_video, result_water_video).to_html5_video())
至此,本次实现先告一段落,关于“多人运动”--合照的解决办法还没来得及探索,欢迎您在评论区分享指导,感谢!
本文分享自华为云社区《"蚂蚁牙黑",快用 ModelArts 自己实现一个!》,原文作者:胡琦 。
转载:https://blog.csdn.net/devcloud/article/details/114278326