繼上一篇 基于Wav2Lip的AI主播 的內(nèi)容之后很多小伙伴反應(yīng)一個問題就是生成的AI人物并不是很清晰,尤其是放到編輯器里會出現(xiàn)明顯的痕跡,因此這次帶來的了 Wav2Lip+GFPGAN 高清版的內(nèi)容,如果不太了解這個項目實做什么的可以來先看一下效果。該項目暫時沒有中文介紹,我這個應(yīng)該是首發(fā)。
這個項目是基于基于Wav2Lip的AI主播 項目的環(huán)境延伸,如果沒有該環(huán)境的請先去該文章進行配置。
基于Wav2Lip自制高清版,用自己形象做數(shù)字人清楚多了
雖然說是自制但是也基于git大佬的源代碼按照自己的需求進行的修改,整體的原理就是基于視頻的每一幀進行高清處理,然后進行合并拼接成視頻,最后拼接音頻形成完整的視頻。
準備工作
- Python環(huán)境需要基于 Anaconda 環(huán)境。Python初學者在不同系統(tǒng)上安裝Python的保姆級指引
- 配置好 GPU 的 Pytorch 環(huán)境。Win10+Python3.9+GPU版pytorch環(huán)境搭建最簡流程
- github上下載源碼,對應(yīng)預(yù)訓(xùn)練模型不用著急,在第一次啟動的時候沒有預(yù)訓(xùn)練模型會自動進行下載。如果網(wǎng)絡(luò)太慢可以將對應(yīng)的下載地址放到迅雷中下載,并復(fù)制到對應(yīng)的項目地址中即可。
- 自行創(chuàng)建虛擬環(huán)境。Python虛擬環(huán)境的安裝和使用
- 如果都不會或者懶的話,直接看文章最下方的的網(wǎng)盤分享一鍵包。
pip 項目依賴
pip install basicsr>=1.3.4.0
pip install facexlib>=0.2.3
pip install lmdb
pip install pyyaml
pip install scipy
pip install tb-nightly
pip install yapf
pip install realesrgan
pip install ffmpeg
pip install torch==1.10.2+cu113 torchvision==0.3.0 --extra-index-url https://download.pytorch.org/whl/cu113
生產(chǎn)流程
首先你要確定幾個生產(chǎn)目錄,即下面代碼中需要使用到的。
- inputs:制作口播視頻的基礎(chǔ)視頻。
- outputs:輸出制作好成品以及基礎(chǔ)數(shù)據(jù)。
inputs 數(shù)據(jù)文件
創(chuàng)建一個自己的項目,例如用自己的昵稱作為文件夾。這里需要將音頻文件和數(shù)字人的視頻文件分開存儲。
腳本會自動的搜索 source_audio 下的文件并在 output 中創(chuàng)建對應(yīng)的文件目錄。
source_video 是你制作數(shù)字人的視頻素材,建議不要超過1分鐘,具體為什么不多說。
執(zhí)行代碼脫手制作
如果對自己機器性能有信心的話可以在下面多進程那個地方解開注釋,使用多進程進行高清處理。
import os
import random
import shutil
import cv2
from tqdm import tqdm
from os import path
import numpy as np
import threading
basePath = "."
# 需要的算法框架目錄
wav2lipFolderName = 'Wav2Lip-master'
gfpganFolderName = 'GFPGAN-master'
wav2lipPath = basePath + '/' + wav2lipFolderName
gfpganPath = basePath + '/' + gfpganFolderName
# 確定需要制作的用戶視頻
userPath = "Mr數(shù)據(jù)楊"
# 獲取本次需要合成視頻的音頻文件
userAudioPathList = os.listdir("inputs/" + userPath + "/source_audio")
for sourceAudioName in userAudioPathList:
# 獲取每個音頻的名稱
title = sourceAudioName.split(".")[-2]
# 每次隨機從用戶的原始文件中提取一個視頻作為素材文件
userVideoPathList = os.listdir("inputs/" + userPath + "/source_video")
sourceVideoName = random.sample(userVideoPathList, 1)[0]
# 輸出項目目錄
outputPath = basePath + "/outputs/" + title
if not os.path.exists(outputPath):
os.makedirs(outputPath)
# 輸入音頻目錄
inputAudioPath = basePath + "/inputs/" + userPath + "/source_audio/" + sourceAudioName
# 輸入視頻目錄
inputVideoPath = basePath + "/inputs/" + userPath + "/source_video/" + sourceVideoName
# 視頻數(shù)據(jù)輸出目錄
lipSyncedOutputPath = basePath + '/outputs/' + title + "/result.mp4"
# wav2lip生成cmd命令行處理數(shù)據(jù)
cmd = "F:\MyEnvsProject\Wav2Lip\python.exe {}/inference.py --checkpoint_path {}/checkpoints/wav2lip_gan.pth --face {} --audio {} --outfile {} --resize_factor 2 --fps 60 --face_det_batch_size 8 --wav2lip_batch_size 128".format(
wav2lipFolderName, wav2lipFolderName, inputVideoPath, inputAudioPath, lipSyncedOutputPath)
os.system(cmd)
# 將視頻中的每一幀生成圖片到目錄中
inputVideoPath = outputPath + '/result.mp4'
unProcessedFramesFolderPath = outputPath + '/frames'
if not os.path.exists(unProcessedFramesFolderPath):
os.makedirs(unProcessedFramesFolderPath)
# gpu_frame = cv2.cuda_GpuMat()
vidcap = cv2.VideoCapture(inputVideoPath)
numberOfFrames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
fps = vidcap.get(cv2.CAP_PROP_FPS)
# print("FPS: ", fps, "Frames: ", numberOfFrames)
for frameNumber in tqdm(range(numberOfFrames)):
_, image = vidcap.read()
cv2.imwrite(path.join(unProcessedFramesFolderPath, str(frameNumber).zfill(4) + '.jpg'), image)
# 高清處理每一幀圖片
cmd = "F:\MyEnvsProject\Wav2Lip\python.exe {}/inference_gfpgan.py -i {} -o {} -v 1.3 -s 2 --only_center_face --bg_upsampler None".format(
gfpganPath,
unProcessedFramesFolderPath,
outputPath)
os.system(cmd)
restoredFramesPath = outputPath + '/restored_imgs/'
if not os.path.exists(restoredFramesPath):
os.makedirs(restoredFramesPath)
processedVideoOutputPath = outputPath
dir_list = os.listdir(restoredFramesPath)
dir_list.sort()
batch = 0
batchSize = 600
for i in tqdm(range(0, len(dir_list), batchSize)):
img_array = []
start, end = i, i + batchSize
print("processing ", start, end)
for filename in tqdm(dir_list[start:end]):
filename = restoredFramesPath + filename;
img = cv2.imread(filename)
if img is None:
continue
height, width, layers = img.shape
size = (width, height)
img_array.append(img)
out = cv2.VideoWriter(processedVideoOutputPath + '/batch_' + str(batch).zfill(4) + '.mp4',
cv2.VideoWriter_fourcc(*'DIVX'), 60, size)
batch = batch + 1
for i in range(len(img_array)):
out.write(img_array[i])
out.release()
# 最終合成視頻
concatTextFilePath = outputPath + "/concat.txt"
concatTextFile = open(concatTextFilePath, "w", encoding='utf8')
for ips in range(batch):
concatTextFile.write("file batch_" + str(ips).zfill(4) + ".mp4\n")
concatTextFile.close()
concatedVideoOutputPath = outputPath + "/concated_output.mp4"
cmd = "ffmpeg -y -f concat -i {} -c copy {}".format(concatTextFilePath, concatedVideoOutputPath)
os.system(cmd)
finalProcessedOutputVideo = processedVideoOutputPath + '/final_with_audio.mp4'
cmd = "ffmpeg -y -i {} -i {} -map 0 -map 1:a -c:v copy -shortest {}".format(concatedVideoOutputPath, inputAudioPath,
finalProcessedOutputVideo)
os.system(cmd)
outputs 數(shù)據(jù)文件
腳本執(zhí)行完畢之后會在對應(yīng)的 output 文件夾生成對應(yīng)的文件目錄。
紅框的文件即最后合成高清的視頻文件。文章來源:http://www.zghlxwxcb.cn/news/detail-806684.html
【分享】Wav2Lip-GFPGAN
百度網(wǎng)盤
夸克網(wǎng)盤 提取碼:3DSr文章來源地址http://www.zghlxwxcb.cn/news/detail-806684.html
到了這里,關(guān)于基于Wav2Lip+GFPGAN的高清版AI主播的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!