当前位置: 首页 > news >正文

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 的原理与应用&#xff0c;其用于优化图像画质。本文关注另外一个相关的项目 Wave2lip&#xff0c;其可以通过人物视频与自定义音频进行适配&#xff0c;改变视频中人物的嘴型与音频对应。 二.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数据处理流程 数据可视化 最终大屏效果 小结 概要 本文的主题是获取下厨房网站月度最佳栏目近十年数据&#xff0c;最终进行数据清洗、处理后生成所需的数据库表&#xff0c;最终进…...

buildadmin+tp8表格操作(5)自定义组装搜索的查询

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

企业级固态硬盘如何稳定运行?永铭固液混合铝电解电容来帮忙

企业级 固态硬盘 永铭固液混合铝电解电容 企业级固态硬盘&#xff08;SSD&#xff09;主要应用于互联网、云服务、金融和电信等客户的数据中心&#xff0c;企业级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&#xff1a;不应该使用三连符 Advisory建议类规范。 2…...

spring boot加mybatis puls实现,在新增/修改时,对某些字段进行处理,使用的@TableField()

1.先说场景&#xff0c;在对mysql数据库表数据插入或者更新时都得记录时间和用户id 传统实现有点繁琐&#xff0c;这里还可以封装一下公共方法。 2.解决方法&#xff1a; 2.1&#xff1a;使用aop切面编程&#xff08;记录一下&#xff0c;有时间再攻克&#xff09;。 2.2&…...

如何构建风险矩阵?3大注意事项

风险矩阵法&#xff08;RMA&#xff09;是确定威胁优先级别的最有效工具之一&#xff0c;可以帮助项目团队识别和评估项目中的风险&#xff0c;帮助项目团队对风险进行排序&#xff0c;清晰地展示风险的可能性和严重性&#xff0c;为项目团队制定风险管理策略提供依据。 如果没…...

SpringSecurity5|12.实现RememberMe 及 实现原理分析

security/day08 这个功能大家还熟悉么&#xff1f;我们在登录网站的时候&#xff0c;除了让你输入用户名和密码&#xff0c;还会有个勾选框&#xff1a; 记住我&#xff01;&#xff01;&#xff01;不是让大家记住我哈。 值得一提的是&#xff0c;Spring Security 也提供了这个…...

持续集成交付CICD:Jenkins Sharedlibrary 共享库

目录 一、理论 1.共享库 2.共享库配置 3.使用共享库 4.共享库扩展 二、实验 1.连接共享库 2.使用共享库 三、问题 1.路径报错 2.readJSON 报错 一、理论 1.共享库 &#xff08;1&#xff09;概念 1&#xff09;共享库这并不是一个全新的概念&#xff0c;其实在编…...

Linux--网络编程

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

数据结构 并查集

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

算法通关村第十六关黄金挑战——求滑动窗口中的最大值(滑动窗口与堆方法、双端队列法和直接比较法)

大家好&#xff0c;我是怒码少年小码。 今天这篇就讲一道题目&#xff0c;不难&#x1f60e;&#xff0c;但是一定要学会自己思考。 滑动窗口最大值 LeetCode 239&#xff1a;给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。…...

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

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

全志H616开发版

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

【Spring boot】RedisTemplate中String、Hash、List设置过期时间

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

Nosql之redis概述及基本操作

关系数据库与非关系型数据库概述 关系型数据库 关系型数据库是一个结构化的数据库&#xff0c;创建在关系模型&#xff08;二维表格模型&#xff09;基础上&#xff0c;一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言&#xff0c;用于执行对关系型…...

使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 驱动编程】

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

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

React Native在HarmonyOS 5.0阅读类应用开发中的实践

一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强&#xff0c;React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 &#xff08;1&#xff09;使用React Native…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...