Wave2Lip 的使用和性能

Wave2Lip usage and performance

提问人:A.J 提问时间:2/21/2022 最后编辑:A.J 更新时间:2/23/2022 访问量:1277

问:

实际问题

目前 opencv 用于在单个文件中写入视频帧。您也可以直接附加音频,还是有其他方法,以便您可以创建小视频片段,这些片段可以通过 rtp 协议广播或直接从 python 代码广播?

out = cv2.VideoWriter(
        'temp/result.avi', 
        cv2.VideoWriter_fourcc(*'DIVX'), 
        fps, 
        (frame_w, frame_h))

... #some frame manipulation happening

out.write(f) # f = video frame

我不想编写视频文件,然后使用 ffmpeg 将其与音频组合。

背景

我正在尝试编写一个需要实时LypSincing的应用程序。 为此,我正在尝试使用 Wave2Lip。 起初,这个库似乎很慢,但实际上可以通过一些优化来非常快。

实验

我首先使用以下命令手动使用另一个视频文件对视频进行lypsinced。

python inference.py --checkpoint_path ptmodels\wav2lip.pth --face testdata\face.mp4 --audio testdata\audio.mp4

face.mp4文件的持续时间为25秒,30fps,分辨率为854*480 audio.mp4 文件的持续时间为 260 秒,30fps,分辨率为 480x360

整个生成过程正好用了 109 秒。 在对代码进行剖析并对其进行分析后,我发现有 2 个部分花费时间最长:

  • 人脸检测部分耗时48.64秒
  • Lypsincing 部分耗时 48.50 秒

然后,我尝试使用静态图像而不是视频,这大大缩短了时间(在我的用例中,我稍后将只使用相同的人脸,因此我将适当地预先计算启动时间的人脸检测)。

python inference.py --checkpoint_path ptmodels\wav2lip.pth --face testdata\face.jpg --audio testdata\audio.mp4
  • 人脸检测部分耗时1.01秒
  • Lypsincing 部分耗时 48.50 秒

在查看了 lypsincing 部分后,我发现整个 lypsincing 视频是生成的,然后与视频相结合

for i, (img_batch, mel_batch, frames, coords) in enumerate(tqdm(gen, 
                                        total=int(np.ceil(float(len(mel_chunks))/batch_size)))):
    if i == 0:
        model = load_model(args.checkpoint_path)
        print ("Model loaded")

        frame_h, frame_w = full_frames[0].shape[:-1]
        out = cv2.VideoWriter('temp/result.avi', 
                                cv2.VideoWriter_fourcc(*'DIVX'), fps, (frame_w, frame_h))

    img_batch = torch.FloatTensor(np.transpose(img_batch, (0, 3, 1, 2))).to(device)
    mel_batch = torch.FloatTensor(np.transpose(mel_batch, (0, 3, 1, 2))).to(device)

    with torch.no_grad():
        pred = model(mel_batch, img_batch)

    pred = pred.cpu().numpy().transpose(0, 2, 3, 1) * 255.
    
    for p, f, c in zip(pred, frames, coords):
        y1, y2, x1, x2 = c
        p = cv2.resize(p.astype(np.uint8), (x2 - x1, y2 - y1))

        f[y1:y2, x1:x2] = p
        out.write(f)

out.release()
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')

然后,我决定用以下结果分析每个 lypsincing 周期:

lypsinc frames generated for batch 0 containing 128 frames with 30.0fps (video part length: 4.26s), took:  3.51s
lypsinc frames generated for batch 1 containing 128 frames with 30.0fps (video part length: 4.26s), took:  0.73s
lypsinc frames generated for batch 2 containing 128 frames with 30.0fps (video part length: 4.26s), took:  0.76s

...

lypsinc frames generated for batch 53 containing 128 frames with 30.0fps (video part length: 4.26s), took:  0.73s
lypsinc frames generated for batch 54 containing 17 frames with 30.0fps (video part length: 0.56s), took:  0.89s

all lypsinc frames generated, took:  48.50s

结论: 解决人脸检测问题(或更像是保持)后,在第一批视频帧准备就绪之前,lypsincing 大约需要 5 秒。每个 lypsinced 视频批次长度为 4.26 秒,计算大约需要 0.8 秒。这意味着,如果要将此视频批量流式传输到音频帧,则应该可以有一个lypsincing,该lypsincing在5秒延迟后开始渲染,而不是在此用例中的50秒。

python opencv 机器学习 deepface deep-fake

评论

0赞 desertnaut 2/21/2022
欢迎来到 SO;请注意,你做了什么和没有做什么的完整故事情节几乎是没有必要的;为简洁起见,请编辑您的帖子,并专注于您的确切问题和疑问。
0赞 Skyler 10/15/2022
我很好奇你是怎么让它渲染得如此之快的,我只有 2.5 分钟估计一个小时和 15 分钟的渲染时间
0赞 Islam Yahia 5/9/2023
嗨,您能否快速更新最适合您的用例的方法?

答: 暂无答案