stable-diffusion不闪动画制作
Q7nl1s admin

安装TemporalKit

用 Stable Diffusion 实现不闪动画制作,Temporal Kit 加 EbSynth

先去下载 Temporal Kit 插件:https://github.com/CiaraStrawberry/TemporalKit.git

image-20230806213126846

点击 Install 后重启 Stable Diffusion,重启后会在一级菜单中看到 Temporal-Kit 页签。

image-20230806213353945

提取关键帧

接着对你要处理的视频进行提取关键帧操作(为什么要提取关键帧?提取关键帧就是把视频中动作变化比较大的画面转成图片,下一步就是对这些图片进行重绘。如果不提取关键帧,而是把视频的每一帧都重绘,一是工作量大,二是重绘的每张图片可能都有点不一样,画面可能闪烁比较严重。)

在 SD WebUI 的主页签中找到 Temporal-Kit,点击打开。然后接着点击“Pre-Processing”,在视频区域这里上传待处理的视频,这是我从抖音上截取的一段(文章最后会提供这个视频的下载地址)。不要马上点击“运行”,还有一些设置,请继续看下文。

image-20230806213732574

在视频下方可以看到这些设置,这些都是针对提取图片的设置:

Sides:生成的 1 张图片的边包含几张视频帧。如果是 2 就代表 4 个视频帧,也就是 2*2;如果是 3 就代表 9 个视频帧,也就是 3*3;最小设置为1,也就是 1 张图包含 1 个视频帧。这个要结合后边的 Height Resolution一起设置。

Height Resolution:生成图片的高度的像素值,建议是:视频的高度 * Sides ,比如我这个视频是 1920*1440,单个视频帧的高度就是 1920,这个公式不是绝对的,你也可以写个 720,或者写个 2048。这个值需要考虑显卡的性能,如果显卡不太行,不要设置的太高。

frames per keyframe:多少视频帧抽取一个关键帧。

fps:视频每秒包含几帧,在电脑上查看视频详情一般可以获取到。

Target Folder:关键帧图片的输出位置,实际会输出到这个目录下创建的一个input文件夹,后续各种处理的中间文件都在这个文件夹下,相当于一个项目目录,所以建议为每个视频的不同处理创建不同的文件夹。注意如果是云端,这里需要是服务器上的目录。

Batch Settings:因为我们这里需要处理整个视频,所以需要把这个Batch Run勾选上。

EBSynth Settings:调成 EBSynth 模式,用于转描视频关键帧

EbSynth官网: https://ebsynth.com/
参考:让你的的画”动”起来 EbSynth介绍及教程_哔哩哔哩_bilibili

image-20230806213904785

image-20230806214711777

注:720P->1280 1080P->1920

参数设置完毕之后,点击页面右侧的“运行”。

image-20230806215359132

image-20230806212352826

关键帧图片都被提取后,图像这个区域会显示提取的首张图片(这里我的卡住了),我们也可以在文件目录中看到提取的图片

image-20230806215529075

然后我们就可以点击“图生图”进入下一步了。

转换风格

在上一步点击“图生图”之后,页面就跳转到“图生图”了,并且自动带过来了首张图片。

image-20230806215745136

我们需要选择一个模型,填写一些提示词。你可以按照自己的需求决定用什么模型和Lora。我这里主要加了点雪的元素

这里的贴出来我的提示词,方便复制。

正面提示词:(8k, best quality, masterpiece, ultra highres:1.2) Photo of Pretty and Cute Chinese woman in the (style of paul rubens and rebecca guay:1.1) (melancholy winter snow:1.4),big eyes

负面提示词: (worst quality:2.0)

然后是一些参数设置,大家根据实际情况来吧,效果不好就调整下。

注意两点:

  • 图片的宽高:这是从提取关键帧的页面带过来的,如果数字太大,建议先调小一点,然后再用超分高清化放大。
  • 重绘强度:不要太大,以免重绘的图片相互之间变化太大,不好衔接,出来的视频会比较闪烁。

image-20230806220030514

我这里把宽高比调成了抖音视频的模式

这里一般还需要 ControlNet 来控一下图,避免重绘的变化太大,也是为了稳定画面。我这里选择的是 Tile 模型,大家也可以试下 SoftEdge、Canny、Lineart 等绘线的模型。

它们的模型下载地址都在这:https://huggingface.co/lllyasviel/ControlNet-v1-1/tree/main

image-20230806220355452

然后就是抽卡了,不断的生成图片,直到你满意。

注意记录下满意图片的生成种子,马上就要用到批量生成中。

image-20230806220500073

将图生图切换到“批量处理”,填写两个目录:

  • 输入目录:提取关键帧步骤中输出图片的目录。
  • 输出目录:重绘图片的保存目录,固定值output,填上就行了。

image-20230806220604833

别忘了 ControlNet 也要设置批处理输入目录

image-20230806230249064

把满意图片的生成种子填写到这里,网上很多教程提到这个,但是不要期望重绘后的每张图片中的元素都能保持一致,因为视频帧的每张图片都是不一样的,一个种子很难稳定输出图片中的各种元素,大家可以自己体会下。

image-20230806220642977

最后就是点击“生成”按钮,等待批处理完成。

image-20230806220704416

在图片输出区域的下方看到这句话,基本就处理完成了。WebUI 的进度有时候更新不及时,注意看控制台或者shell的输出。

image-20230806220755903

合成视频

现在进入激动人心的视频合成环节了,这一步需要回到 Temporal-Kit 页面。

image-20230806221230487

我们先把项目路径填上,再点击读取配置,设置参数就自动加载好了,这里唯一需要调整的就是尺寸,我原先的配置为1920,这里就设置为1920

image-20230806221258166

点击 prepare ebsynth 就可以进入下一步了

剩下的工作就交给自动化助手软件了(这个只在社群里有,我不提供)

image-20230806221930373

在上面填入 EbSynth 路径,在下方填入工作目录的路径,点击启动

image-20230806222138517

上面操作均为自动化部署完成(自动部署期间不要动鼠标或者键盘,很快的)

image-20230806221912626

等跳出此窗口后,查看上述任务是否完成,完成无误后,再最后点击一次 recombine ebsynth 按钮,视频就做完了

image-20230807003612729

效果如下:

image-20230807015743928

我再写个脚本让前后视频做个对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import cv2
import os
from tqdm import tqdm

# 指定输出视频路径
output_video_path = 'C:/Users/Administrator/Downloads/Video/output.mp4'

input_video = 'C:/Users/Administrator/Downloads/Video/begin.mp4'
output_video = 'C:/Users/Administrator/Downloads/Video/output_3.mp4'

# 设置输出视频的帧率和分辨率
output_fps = 24 # 输出视频的帧率
output_width, output_height = None, None # 输出视频的分辨率,默认与输入视频相同

# 打开输入视频文件
cap = cv2.VideoCapture(input_video)

# 获取输入视频的帧率和总帧数
input_fps = cap.get(cv2.CAP_PROP_FPS)
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))

# 确定输出视频的分辨率
if output_width is None or output_height is None:
output_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
output_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 读取原视频和上色视频
original_video = cv2.VideoCapture(input_video)
colorized_video = cv2.VideoCapture(output_video)

# 获取原视频帧率和尺寸
fps = original_video.get(cv2.CAP_PROP_FPS)
frame_width = int(original_video.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(original_video.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 创建输出视频
output_video = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (2 * frame_width, frame_height))

# 使用tqdm包装视频迭代,并显示进度条
with tqdm(total=total_frames, unit='frame') as pbar:
# 逐帧读取原视频和上色视频,并进行合并
while original_video.isOpened() and colorized_video.isOpened():
original_ret, original_frame = original_video.read()
colorized_ret, colorized_frame = colorized_video.read()

if not original_ret or not colorized_ret:
break

# 将原视频和上色视频按照一定布局合并为一个帧
combined_frame = cv2.hconcat([original_frame, colorized_frame])

# 将帧写入输出视频
output_video.write(combined_frame)

# 更新进度条
pbar.update(1)


# 释放视频资源
original_video.release()
colorized_video.release()
output_video.release()

实现的效果如下

image-20230807015914349

由于没有音频源,我们再在 pr 中加入音轨

image-20230807014759060

最后导出后视频是这样的

Video Player

累死小爷了

 Comments
Comment plugin failed to load
Loading comment plugin
Powered by Hexo & Theme Keep
Unique Visitor Page View