Python - Wave2lip 环境配置与 Wave2lip x GFP-GAN 实战 [超详细!]

一.引言

前面介绍了 GFP-GAN 的原理与应用,其用于优化图像画质。本文关注另外一个相关的项目 Wave2lip,其可以通过人物视频与自定义音频进行适配,改变视频中人物的嘴型与音频对应。

二.Wave2Lip 简介

Wave2lip 研究 lip-syncing 以达到视频匹配目标语音片段的目的。目前的作品擅长在训练阶段看到的特定人的静态图像或视频。然而,它们无法准确地改变动态、无约束的谈话面部视频中的任意身份。通过学习强大的唇同步鉴别器来解决它们。接下来,我们提出了新的、严格的评估基准以及在无约束视频中精确测量嘴唇同步的度量。对我们具有挑战性的基准进行了广泛的定量评估,结果表明视频的唇同步准确性几乎和真正同步的一样好。

论文地址: https://arxiv.org/pdf/2008.10010.pdf 

1.Wave2Lip 训练数据

训练中用到了LRS2 数据集,该数据集由英国广播公司电视台的数千句口语组成。每句话的长度不超过100个字符。训练、验证和测试集根据广播日期进行划分。数据集统计数据如下表所示。

预训练集中的话语对应于部分句子和多个句子,而训练集仅由单个完整句子或短语组成。预训练和训练之间有一些重叠。

2.Wave2Lip 训练目标

wav2lip 模型的训练由生成器和判别器共同组成。GAN 负责学习音频-图像之间的对应关系,生成同步的嘴唇动作。判别器负责评估图像-音频的同步性。具体的,音频会被处理为音频 chunk 并处理转换为梅尔频谱矩阵,该矩阵常用于信号处理中的音频频谱特征;视频则是会逐帧抽取,转化为 [Channel、width、height] 的多通道矩阵。通过训练频谱矩阵与图像多通道矩阵的对应关系,学习chunk 与视频帧中口型的对应关系,不断地反馈训练以优化视频与音频的同步效果。

3.Wave2Lip 模型推理

wave2lip 实战中大致遵循下述流程,下述流程扩展为整个视频图像帧,即可实现视频与音频的嘴型对应:

解析视频文件

这里一般最常用的格式即为 mp4,通过 cv2 库的 VideoCapture 解析视频文件,并通过 video_stream 流式读取视频的每一帧,更简单的,你的视频可以是一张人物的 Face 图,这样会将图像复制扩展为与音频匹配的帧数。

音频文件解析

使用 audio 库处理音频文件,为了统一,这里会使用 ffmepg 将音频文件统一转换为 wav 格式。随后通过 melspectrogram 方法获取 wav 音频的梅尔频谱矩阵并将矩阵转换为多个 chunk。

人脸识别模块

针对视频帧识别人脸位置对应的 coord 坐标,因此 Wave2lip 实现中还需要一个 face-detect 的模型,用于对每一帧图像中人脸进行定位。

GAN 生成

基于上面的人脸的图像通道数字矩阵与音频的 mel 频谱矩阵构造模型的输入,通过调用 GAN 模型生成对应音频的嘴型图像。

图像拼接与重建

将预测得到的 pred 和 coord 坐标结合,替换原图中的人脸部分,实现人脸与嘴型的替换。

三.Wave2lip 环境搭建

 代码实现: https://github.com/Rudrabha/Wav2Lip

1.Package 安装

python 3.6

conda create -n wave2lip python=3.6
conda activate wave2lip

ffmpeg

ffmpeg 主要用于音频文件转换为 wav 格式

sudo apt-get install ffmpeg

requirements

下载 Wave2lip 对应的 github 项目,安装对应的依赖:

librosa==0.7.0
numpy==1.17.1
opencv-contrib-python>=4.2.0.34
opencv-python==4.1.0.25
torch==1.1.0
torchvision==0.3.0
tqdm==4.45.0
numba==0.48
pip install -r requirements.txt

face detection model

模型下载地址: 预训练模型

备用下载地址: 备用节点下载

下载好的 .pth 模型需要放置到项目对应的 face_detection/detection/sfd/s3fd.pth 路径下:

2.模型 weights 下载

 Wave2lip: Highly accurate lip-sync

README 中给出了 4 个模型 weights,大小在 50M - 500M 之间,其有各自不同的擅长,有的擅长口型对应,有的擅长图像质量。不过博主测试只有第一个模型可以跑通,其他模型跑通的同学也欢迎在评论区一起交流。

四.Wave2lip X GFP-GAN 实战

1.参数配置

python inference.py --checkpoint_path <ckpt> --face <video.mp4> --audio <an-audio-source> 

-- checkpoint_path 模型地址

-- face 要修改的视频,也可以是静态图

-- audio 要适配的音频

其他参数: 

-- pads 调整检测到的面部边界框。通常会带来更好的结果。

-- nosmooth 如果嘴巴位置错位或有伪影,可能是过度平滑了人脸检测,加入该参数重试。

-- resize_factor 修改缩放参数以获得较低分辨率的视频。因为原模型是在低分辨率人脸数据上训练的,因此 720p 视频可能比 1080p 视频获得更好更逼真的效果。

还有一些参数可以参考 inference.py 的 args parse 模块,这里有完整的参数解析。

2.Wave2lip 运行

为了方便,我们将官方给的示例调整一下:

#!/bin/bashckpt='/data2/wav2lip/checkpoints/wav2lip.pth'
video='/data2/wav2lip/video/zgl.jpg'
audio='/data2/wav2lip/mp3/AutumnWillNotComeBack.mp3'python inference.py --checkpoint_path $ckpt --face $video --audio $audio

◆ 视频选择

为了简化流程,我们使用单一人物图像的 jpeg,当然上传人物的 video.mp4 也可以,但是需要保证每一帧都可以获取 face-detect 的结果,否则程序会异常报错。

◆ 音频选择

AutumnWillNotComeBack.mp3,相信 90 后的你一定不会陌生,没错这就是 《秋天不回来》!

​运行命令后会显示音频的相关信息,可以看到原始的 mp4 格式已经处理为 wav,处理命令为:

command = 'ffmpeg -y -i {} -i {} -strict -2 -q:v 1 {}'.format(args.audio, 'temp/result.avi', args.outfile)
subprocess.call(command, shell=platform.system() != 'Windows')

◆ 输出结果

输出会通过 cv2.VideoWriter 写入对应的 output 目录,下面为生成视频的相关信息:

结合前面的介绍的 Nginx 服务,我们可以直接在本机查看服务器上生成的视频,非常的方便。

Nginx 服务搭建:  Nginx - 本机读取服务器图像、视频

3.GFP-GAN 修复

由于我们原图的画质较低,导致后续生成的视频也比较模糊。最简单的优化方案是在原始图片、视频的选择上选取更加清晰的版本。不过即便如此嘴部动作也会有一些模型和重影,下面我们基于 GFP-GAN 对视频进行清晰度重建。

Video2PNG

通过 VideoFileClip 库处理视频,共获取 FPS x Duration/s 帧图像。

def video_to_png(_file_name, _output):from moviepy.editor import VideoFileClip# Load your gifclip = VideoFileClip(_file_name)print(f'Duration: {clip.duration} FPS: {clip.fps}')# Loop over clip framesfor i, frame in enumerate(clip.iter_frames()):from PIL import Imageimg = Image.fromarray(frame)img.save(f'{_output}/frame_{i}.png')

GFP-GAN ReBuild

GFP-GAN 服务搭建: Python - GFPGAN + MoviePy 提高人物视频画质

python inference_gfpgan.py -i inputs/gif_imgs -o results -v 1.3 -s 2

原视频 FPS = 25,共 2 min = 120 s,所以修复后生成 3k 帧图像。 

PNG2Video

将上述 3000 帧图像的地址构造生成 image_files 并生成 ImageSequenceClip 对象,通过 set_audio 的方法匹配 Wave2lip 生成视频的 Audio,最终 write_videofile 输出 mp4。

def png_to_mp4(_file_name, input):# Load your gifclip = VideoFileClip(_file_name)print(f'Duration: {clip.duration} FPS: {clip.fps}')# Loop over clip framesimage_files = get_images(_file_name, input)new_clip = ImageSequenceClip(image_files, fps=clip.fps)# 设置音频剪辑到图像序列剪辑image_sequence = new_clip.set_audio(clip.audio)# 导出最终视频image_sequence.write_videofile('output_video.mp4', codec='libx264', audio_codec='aac', fps=clip.fps)

可以看到修复后的视频,人物的脸部和嘴部轮廓形状也更加清晰:

五.总结

通过上面一系列的操作,我们最终实现了  Wave2lip x GFP-GAN 的操作。不过 2min 的视频里,人物的嘴型还是有飘忽不定和重影的问题,一方面可能是由于原图、视频的画质质量过低导致;其次古装人物的胡须与训练集中欧美人的脸部造型差异可能也是原因之一,后续博主也会按 Github 给出的建议,添加 --nosmooth 参数看看是否有好转。有问题欢迎大家评论区交流讨论 ~ 👍

Tips:

Wave2lip 和 GFP-GAN 对应两套 conda 的 python 环境,部署时需要区分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/153109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot的地方美食分享网站(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的地方美食分享网站(有报告)。Javaee项目&#xff0c;springboot项目。 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 项目介绍&#xff1a; 采用…

常见树种(贵州省):009楠木、樟木、桂木种类

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、楠木 …

【腾讯云云上实验室-向量数据库】探索腾讯云向量数据库:全方位管理与高效利用多维向量数据的引领者

目录 前言1 腾讯云向量数据库介绍2 向量数据库信息及设置2.1 向量数据库实例信息2.2 实例监控2.3 密钥管理2.4 安全组2.5 Embedding2.6 可视化界面 3 可视化界面4 Embedding4.1 embedding_coll精确查询4.2 unenabled_embedding_coll精确查询 5 数据库5.1 创建数据库5.2 插入数据…

NTLM 认证支持的添加与实现

我在psf/requests项目中报告了bug #932&#xff0c;并提出了一个关于支持HTTP NTLM认证的问题。这篇文章将详细介绍问题背景和解决方案。 HTTP NTLM认证是一种用于验证用户身份的协议。在某些场景下&#xff0c;用户可能需要使用NTLM认证才能访问某些网站或资源。然而&#xff…

SpringCloud 微服务全栈体系(十五)

第十一章 分布式搜索引擎 elasticsearch 五、RestClient 操作文档 为了与索引库操作分离&#xff0c;再次参加一个测试类&#xff0c;做两件事情&#xff1a; 初始化 RestHighLevelClient酒店数据在数据库&#xff0c;需要利用 IHotelService 去查询&#xff0c;所以注入这个接…

Linux shell编程学习笔记28:脚本调试 set命令

0 引入 在Linux Shell 脚本编程的过程中&#xff0c;编写简单功能的脚本&#xff0c;代码不多&#xff0c;一般阅读起来没什么难度&#xff0c;有问题也比较有查出原因和修正。但是当脚本要实现的功能较多&#xff0c;代码变得较为复杂时&#xff0c;阅读起来就不那么容易看明…

一道简单的积分题目

题目如下图&#xff1a; 解法1&#xff1a; 解法2&#xff1a; 解法3&#xff1a; 错误做法&#xff1a; 在 x ∈ ( 0 , ∞ ) 上有 ln ⁡ x < x &#xff0c;令 f ( x ) ln ⁡ x 1 x 2 &#xff0c; g ( x ) &#xff1d; x 1 x 2 ∴ f ( x ) < g ( x ) &#x…

Qt按钮大全续集(QCommandLinkButton和QDialogButtonBox )

## QCommandLinkButton 控件简介 QCommandLinkButton 控件中文名是“命令链接按钮”。QCommandLinkButton 继承QPushButton。CommandLinkButton 控件和 RadioButton 相似,都是用于在互斥选项中选择一项。表面上同平面按钮一样,但是 CommandLinkButton 除带有正常的按钮上的文…

SpringCloud之Feign

文章目录 前言一、Feign的介绍二、定义和使用Feign客户端1、导入依赖2、添加EnableFeignClients注解3、编写FeignClient接口4、用Feign客户端代替RestTemplate 三、自定义Feign的配置1、配置文件方式全局生效局部生效 2、java代码方式 四、Feign的性能优化连接池配置 五、Feign…

代码随想录算法训练营第六十天丨 单调栈03

84.柱状图中最大的矩形 思路 单调栈 本地单调栈的解法和接雨水的题目是遥相呼应的。 为什么这么说呢&#xff0c;42. 接雨水 (opens new window)是找每个柱子左右两边第一个大于该柱子高度的柱子&#xff0c;而本题是找每个柱子左右两边第一个小于该柱子的柱子。 这里就涉…

从入门到精通,mac电脑录屏软件使用教程!

“mac电脑怎么录屏呀&#xff0c;刚买了一台mac电脑&#xff0c;用了几个月感觉挺流畅的&#xff0c;最近因为工作原因&#xff0c;需要用到录屏功能&#xff0c;但是我不会操作&#xff0c;想问问大家有没有简单易懂的录屏教程&#xff0c;谢谢啦。” 在日常生活中&#xff0…

几个强力的nodejs库

几个强力的nodejs库 nodejs被视为许多Web开发人员的理想运行时环境。 nodejs的设计是为了在运行时中使用JavaScript编写的代码&#xff0c;它是世界上最流行的编程语言之一&#xff0c;并允许广泛的开发者社区构建服务器端应用程序。 nodejs提供了通过JavaScript库重用代码的…

FastJsonAPI

maven项目 pom.xml <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>2.0.26</version></dependency><dependency><groupId>junit</groupId>&l…

Java读写Jar

Java提供了读写jar的类库Java.util.jar&#xff0c;Java获取解析jar包的工具类如下&#xff1a; import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.util.Enumeration; import java.util.HashMap; import …

【图像分类】【深度学习】【Pytorch版本】ResNet模型算法详解

【图像分类】【深度学习】【Pytorch版本】 ResNet模型算法详解 文章目录 【图像分类】【深度学习】【Pytorch版本】 ResNet模型算法详解前言ResNet讲解Deep residual learning framework(深度残差学习框架)残差结构(Residuals)ResNet模型结构 ResNet Pytorch代码完整代码总结 前…

【练习】检测U盘并自动复制内容到电脑的软件

软件作用&#xff1a; 有U盘插在电脑上后&#xff0c;程序会检测到U盘的路径。 自己可以提前设置一个保存复制文件的路径或者使用为默认保存的复制路径&#xff08;默认为桌面&#xff0c;可自行修改&#xff09;。 检测到U盘后程序就会把U盘的文件复制到电脑对应的…

PyTorch微调终极指南1:预训练模型调整

如今&#xff0c;在训练深度学习模型时&#xff0c;通过根据自己的数据微调预训练模型来进行迁移学习&#xff08;transfer learning&#xff09;已成为首选方法。 通过微调这些模型&#xff0c;我们可以利用他们的专业知识并使它们适应我们的特定任务&#xff0c;从而节省宝贵…

【miniQMT实盘量化4】获取实时行情数据

前言 上篇&#xff0c;我们介绍了如何获取历史数据&#xff0c;有了历史数据&#xff0c;我们可以进行分析和回测。但&#xff0c;下一步&#xff0c;我们更需要的是实时数据&#xff0c;只有能有效的监控实时行情数据&#xff0c;才能让我们变成市场上的“千里眼&#xff0c;…

从0开始学习JavaScript--深入探究JavaScript类型化数组

JavaScript类型化数组是一种特殊的数组类型&#xff0c;引入了对二进制数据的更底层的操作。这种数组提供了对内存中的二进制数据直接进行读写的能力&#xff0c;为处理图形、音频、视频等大规模数据提供了高效的手段。本文将深入探讨JavaScript类型化数组的基本概念、常见类型…

场景交互与场景漫游-对象选取(8-2)

对象选取示例的代码如程序清单8-11所示&#xff1a; /******************************************* 对象选取示例 *************************************/ // 对象选取事件处理器 class PickHandler :public osgGA::GUIEventHandler { public:PickHandler() :_mx(0.0f), _my…