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 环境,部署时需要区分。
相关文章:

Python - Wave2lip 环境配置与 Wave2lip x GFP-GAN 实战 [超详细!]
一.引言 前面介绍了 GFP-GAN 的原理与应用,其用于优化图像画质。本文关注另外一个相关的项目 Wave2lip,其可以通过人物视频与自定义音频进行适配,改变视频中人物的嘴型与音频对应。 二.Wave2Lip 简介 Wave2lip 研究 lip-syncing 以达到视频…...

2311rust,1.31版本更新
1.31.0稳定版 Rust1.31可能是最激动人心的版本! 使用Cargo创建一个新项目: cargo new foo以下是Cargo.toml的内容: [package] name "foo" version "0.1.0" authors ["名字"] edition "2018" //版本. [dependencies]在[package]…...

文心一言-情感关怀之旅
如何让LLM更有温度。 应用介绍...

下厨房网站月度最佳栏目菜谱数据获取及分析PLus
目录 概要 源数据获取 写Python代码爬取数据 Scala介绍与数据处理 1.Sacla介绍 2.Scala数据处理流程 数据可视化 最终大屏效果 小结 概要 本文的主题是获取下厨房网站月度最佳栏目近十年数据,最终进行数据清洗、处理后生成所需的数据库表,最终进…...

buildadmin+tp8表格操作(5)自定义组装搜索的查询
有时候我们会自定义组装一些数据,发送给后端,让后端来进行筛选,这里有一个示例 const onComSearchIdEq () > {// 展开公共搜索baTable.table.showComSearch true/*** 公共搜索表单赋值* 范围搜索有两个输入框,输入框绑定变量…...

企业级固态硬盘如何稳定运行?永铭固液混合铝电解电容来帮忙
企业级 固态硬盘 永铭固液混合铝电解电容 企业级固态硬盘(SSD)主要应用于互联网、云服务、金融和电信等客户的数据中心,企业级SSD具备更快传输速度、更大单盘容量、更高使用寿命以及更高的可靠性要求。 企业级固态硬盘的运行要求—固液混合电…...

【MISRA C 2012】Rule 4.2 不应该使用三连符
1. 规则1.1 原文1.2 分类 2. 关键描述3. 代码实例 1. 规则 1.1 原文 Rule 4.2 Trigraphs should not be used Category Advisory Analysis Decidable, Single Translation Unit Applies to C90, C99 1.2 分类 规则4.2:不应该使用三连符 Advisory建议类规范。 2…...

spring boot加mybatis puls实现,在新增/修改时,对某些字段进行处理,使用的@TableField()
1.先说场景,在对mysql数据库表数据插入或者更新时都得记录时间和用户id 传统实现有点繁琐,这里还可以封装一下公共方法。 2.解决方法: 2.1:使用aop切面编程(记录一下,有时间再攻克)。 2.2&…...

如何构建风险矩阵?3大注意事项
风险矩阵法(RMA)是确定威胁优先级别的最有效工具之一,可以帮助项目团队识别和评估项目中的风险,帮助项目团队对风险进行排序,清晰地展示风险的可能性和严重性,为项目团队制定风险管理策略提供依据。 如果没…...

SpringSecurity5|12.实现RememberMe 及 实现原理分析
security/day08 这个功能大家还熟悉么?我们在登录网站的时候,除了让你输入用户名和密码,还会有个勾选框: 记住我!!!不是让大家记住我哈。 值得一提的是,Spring Security 也提供了这个…...

持续集成交付CICD:Jenkins Sharedlibrary 共享库
目录 一、理论 1.共享库 2.共享库配置 3.使用共享库 4.共享库扩展 二、实验 1.连接共享库 2.使用共享库 三、问题 1.路径报错 2.readJSON 报错 一、理论 1.共享库 (1)概念 1)共享库这并不是一个全新的概念,其实在编…...

Linux--网络编程
一、网络编程概述1.进程间通信: 1)进程间通信的方式有**:管道,消息队列,共享内存,信号,信号量这么集中 2)特点:依赖于linux内核,基本是通过内核来实现应用层…...

数据结构 并查集
作用 快速的处理以下问题:【近乎O(1)的时间完成】 1.将两个集合合并 2.询问两个元素是否在一个集合中 用树的形式维护集合 基本原理 每一个集合用一棵树表示 每一个集合的编号就是根结点的编号,对于每一个结点,都存储其父结点…...

算法通关村第十六关黄金挑战——求滑动窗口中的最大值(滑动窗口与堆方法、双端队列法和直接比较法)
大家好,我是怒码少年小码。 今天这篇就讲一道题目,不难😎,但是一定要学会自己思考。 滑动窗口最大值 LeetCode 239:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。…...

常见树种(贵州省):009楠木、樟木、桂木种类
摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、楠木 …...

全志H616开发版
开发板介绍: 二、开发板刷机 SDFormatter TF卡的格式化工具、Win32Diskimager 刷机工具 刷机镜像为:Orangepizero2_2.2.0_ubuntu_bionic_desktop_linux4.9.170.img 使用MobaXterm_Personal_20.3连接使用 网络配置:nmcli dev wifi 命令接入网…...

【Spring boot】RedisTemplate中String、Hash、List设置过期时间
文章目录 前言Redis中String设置时间的方法Redis中Hash和List设置时间的方法Redis中Hash的put、putAll、putIfAbsent区别 前言 时间类型:TimeUnit import java.util.concurrent.TimeUnit;TimeUnit.SECONDS:秒 TimeUnit.MINUTES:分 TimeUnit.HOURS&…...

Nosql之redis概述及基本操作
关系数据库与非关系型数据库概述 关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型…...

使ros1和ros2的bag一直互通
很多文章都是先source ros1 然后source ros2,再play bag source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash ros2 bag play -s rosbag_v2 kitti_raw00.bag 但实测会出问题: 为使ros1和ros2的bag一直互通 sudo apt update sudo apt install ros-foxy-ro…...

【正点原子 linux 驱动编程】
在此声明,正用点编的说明书真的拉,丝毫不具备兼容性。。比如linux的第一个实验,其中包含的 unregister_chrdev_region 函数,fileoperation 结构体等均来自 <linux/fs.h> 文件,搞不懂,他们方ide.h&…...

使用Python的turtle模块绘制玫瑰花图案(含详细Python代码与注释)
1.1引言 turtle模块是Python的标准库之一,它提供了一个绘图板,让我们可以在屏幕上绘制各种图形。通过使用turtle,我们可以创建花朵、叶子、复杂的图案等等。本博客将介绍如何使用turtle模块实现绘制图形的过程,并展示最终结果。 …...

Redis学习笔记14:基于spring data redis及lua脚本ZSET有序集合实现环形结构案例及lua脚本如何发送到redis服务器
案例实现目标,一、实现一个环形结构,环形结构上节点有一个阀值threshold,超过阀值则移除分数score最低的成员,不足则将当前成员添加进环中,且确保成员不可重复;二、每次访问环中的数据都需要刷新key的过期时间…...

openssl C++研发之pem格式处理详解
一、PEM_writeXXX和EM_write_bio_XXX 在OpenSSL的crypto/pem.h头文件中,PEM_write_XXXX和PEM_write_bio_XXXX系列函数用于将特定类型的数据写入文件或BIO(内存缓冲区)中,其中XXXX代表不同的数据类型。 这些函数的使用方式相似&a…...

【教3妹学编辑-mysql】详解数据库三大范式
什么是范式 简单地理解就是:数据库设计时遵循的规范 三大范式 数据库三大范式包含:1、第一范式(1NF);2、第二范式(2NF);3、第三范式(3NF)。其中,第一范式(1NF)的要求是属性不可分割,第二范式(2NF)的要求是…...

【计算机网络笔记】路由算法之链路状态路由算法
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...

读像火箭科学家一样思考笔记04_第一性原理(下)
1. 来自无形规则的阻力 1.1. 无形规则 1.1.1. 僵化成规则的不必要习惯和行为 1.1.2. 不像有形的书面规则 1.1.2.1. 书面规则出现在标准操作流程中,可以修改或删除 1.1.3. 成文的规则可能会抗拒变革,但无形规则却更加顽固 1.1.4. 我们为强加在自己身…...

开源集群管理系统对比分析:Kubernetes 与 Apache Mesos
集群管理系统是关键的软件解决方案,可以在互连机器网络中有效分配和利用计算资源。毫无疑问,它们通过确保可扩展性、高可用性和有效的资源管理在现代计算中发挥着至关重要的作用,这使得它们对于运行复杂的应用程序、管理数据中心以及进一步增…...

matlab 坡度滤波算法地面分割
目录 一、算法原理1、实现流程2、参考文献二、代码实现三、结果展示四、测试数据一、算法原理 1、实现流程 1、格网示意图 2、计算格网行列数 公式中的特殊符号为向上取整,...

【腾讯云 HAI域探秘】高性能服务器引领AI革新浪潮:从AI绘画、知识问答到PyTorch图像分类、视频检测的全方位探索
目录 1 HAI(高性能应用服务)简介2 HAI的应用场景2.1 HAI在AI作画中的灵活性与效率2.2 深入探索LLM语言模型的应用与性能2.3 HAI支持的AI模型开发环境与工具 3 基于stable difussio的AI 绘画应用实践3.1 使用AI模型中的stable diffusion模型服务3.2 设置和…...

【Java】ExcelWriter自适应宽度工具类(支持中文)
工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...