稳定扩散 Parseq
这是什么?
你可以直接进入 Parseq:https://sd-parseq.web.app/ 。
一些背景介绍:
- Stable Diffusion 是一种AI图像生成工具。
- Deforum 是一个基于笔记本的稳定扩散UI,主要用于创建视频。
- AUTOMATIC1111/stable-diffusion-webui 是一个稳定扩散的Web UI(但不适用于Deforum)。
- Deforum扩展用于Automatic1111 是一个扩展,集成了Deforum笔记本的功能,用于Automatic1111 Web UI。
Parseq(此工具)是用于Automatic1111的Deforum扩展的参数序列器。你可以使用它生成动画,对许多稳定扩散参数(如种子、比例、提示权重、噪声、图像强度等)进行紧密控制和灵活插值,以及输入处理参数(如缩放、平移、3D旋转等)。
目前,Parseq几乎完全是前端的,默认情况下将所有状态存储在浏览器本地存储中。所有处理,包括音频处理,都在浏览器中完成。登录用户可以选择从UI上传他们的作品,以便于分享。
使用Parseq,你可以:
使用脚本逻辑在提示文本中进行序列、演化和混合提示 | 控制参数和提示权重随时间的变化,可以以可视化和高级表达语言来实现 | 自动检测音频事件,并使用它们来影响你的视频。 |
从音频中提取音调和幅度数据,并导入任何原始时间序列数据,用于表达式 | 在开始扩散之前预览3D运动和最终提示 | 与A1111的Deforum扩展的简单集成——只需复制一个链接就行了! |
有什么新内容?
请参见项目维基中的 Parseq 更新日志 。
开始使用
先决条件
- 首先确保你有一个工作的Automatic1111的稳定扩散UI安装。
- 接下来,安装 Deforum扩展。
– 你现在应该在
Deforum
扩展下的Init
标签页的底部看到一个“Parseq”部分(点击展开)。
逐步提升
了解Parseq功能和核心概念的最佳方式是观看以下教程:这几个教程视频:
使用
总而言之,有两个步骤需要执行:
步骤1:创建参数清单
- 访问 https://sd-parseq.web.app/(或从此仓库运行UI,使用
npm start
) - 编辑顶部的表格以指定你的关键帧和这些关键帧的参数值。详见下面关于你能做什么的更多信息。
- 复制底部“输出”文本框的内容。如果你已登录(通过右上角的按钮),你可以选择上传输出,然后复制生成的URL。所有后续更改都将推送到同一URL,因此你无需再次复制和粘贴。
步骤2:生成视频
- 转到SD网页UI,进入Deforum选项卡,然后点击Init选项卡。
- 将步骤1中复制的JSON或URL粘贴到页面底部的Parseq部分。
- 调整任何其他Deforum / 稳定扩散设置。特别记住检查动画模式,FPS和总帧数,以确保它们与Parseq匹配。
- 点击生成。
示例
这里有一些示例展示了可以做什么。这些大部分在20fps下生成,然后用ffmpeg的minterpolate或FILM平滑到60fps。参见Parseq 示例库,查看一系列简单示例及重现所需的所有设置。
示例 | 描述 |
---|---|
音频控制提示:振幅影响面部表情,音高影响粉彩/矢量效果。查看 YouTube 上的视频 以获得更高质量和所有设置。 | |
源自 Parseq 教程3 的音频同步示例。查看 YouTube 上的高质量版本。 | |
另一个高级音频同步示例。有关其创建的详细描述请见此处。音乐节选自 The Prodigy - Smack My Bitch Up (Noisia Remix)。 | |
结合3D Y轴旋转和X轴平移,围绕对象进行旋转。更多信息请见 Parseq 示例库。 | |
在 Parseq 教程2 中展示的种子传播示例。 | |
在 Parseq 教程2 中展示的提示操控示例。 | |
在几个著名面孔之间振荡,并带有一些3D移动和偶尔的去噪峰值以重置上下文。 |
特性
具备脚本插值的关键帧参数值
Parseq 的主要特点是通过关键帧和有趣的插值机制对参数值进行高级控制。
关键帧网格是 Parseq 中的核心用户界面概念。网格中的每一行代表一个关键帧。每个参数有两列:第一列接受该字段的显式值,第二列接受一个 插值公式,定义该值如何“旅行”到下一个关键帧的值。如果在给定关键帧上没有指定插值公式,则继续使用上一个关键帧的公式。默认的插值算法是线性插值。
在网格下方,有一个图表可以让你看到插值的结果(并通过拖动节点来编辑关键帧值):
插值公式可以是任意复杂的数学表达式,并且可以使用一系列内置函数和值,包括振荡器和和帮助程序来同步它们的时间戳或节拍:
插值表达式
插值表达式定义了在每一帧中给定字段的值应如何计算。表达式可以返回数字或字符串。字符串字面量必须用双引号(""
)括起来。
以下是你可以在 Parseq 表达式中使用的操作符、值、常量和函数。
函数实时文档
💡 你可以使用 Parseq 的实时文档 来可视化和操作所有插值逻辑。💡
操作符
操作符 | 描述 | 示例 |
---|---|---|
<expr1> + <expr2> | 两个表达式相加。如果任一表达式为字符串,也可充当字符串连接(与 JavaScript 字符串连接的类型转换语义相同)。 | 使种子在每一帧增加0.25(Parseq 使用分数种子来影响子种子的强度): |
<expr1> - <expr2> | 减去两个表达式。 | |
<expr1> * <expr2> | 两个表达式相乘。 | |
<expr1> / <expr2> | 两个表达式相除。 | |
<expr1> % <expr2> | 取模 | 每4拍重置种子: |
<expr1> != <expr2> | 如果表达式不相等,返回1,否则返回0。 | |
<expr1> == <expr2> | 如果表达式相等,返回1,否则返回0。 | |
<expr1> < <expr2> | 如果 <expr1> 小于 <expr2> ,返回1,否则返回0。 | |
<expr1> <= <expr2> | 如果 <expr1> 小于或等于 <expr2> ,返回1,否则返回0。 | |
<expr1> >= <expr2> | 如果 <expr1> 大于 <expr2> ,返回1,否则返回0。 | |
<expr1> < <expr2> | 如果 <expr1> 大于或等于 <expr2> ,返回1,否则返回0。 | |
<expr1> and <expr2> | 如果 <expr1> 和 <expr2> 都不为0,返回1,否则返回0。 | |
<expr1> or <expr2> | 如果 <expr1> 或 <expr2> 不为0,返回1,否则返回0。 | |
if <cond> <consequent> else <alt> | 如果 cond 评估为任何非0值,返回 consequent ,否则返回 alt 。cond 、consequent 和 alt 都是任意表达式。 | 使用方波在1和-1之间交替渲染步函数和三次样条插值,周期为10帧: |
<expr1> : <expr2> | 简化语法,便于创建格式为 (<term>:<weight>) 的字符串。例如,在提示中放入 ${"cat":prompt_weight_1} 会渲染为 ${(cat:0.5)} ,其中0.5是该帧的 prompt_weight_1 值。expr1 必须返回一个字符串,expr2 返回一个数字。 |
上下文变量
你的表达式在一个上下文中运行,该上下文提供了一些有用的变量:
值 | 描述 | 示例 |
---|---|---|
L | (默认) 假设当前帧在前后关键帧值之间的线性插值值 | |
S | 假设当前帧的值为阶跃插值。这相当于 active_keyframe_value ,即值列中最后看到的值。 | |
C | 假设当前帧的值为所有关键帧值的三次样条插值。 | |
P | 同上,但使用多项式插值。与三次样条非常相似。 | |
f | 当前帧编号。单独使用不太有用,但可以在插值算法中引用整体视频的位置。例如,将其添加到种子值中,每帧递增种子。 | |
k | 自这个字段的活动关键帧开始以来经过的帧数 | |
b | 当前的节拍位置。取决于BPM和FPS。 | |
s | 当前的秒数位置。取决于FPS。 | |
active_keyframe | 该字段当前活动关键帧的帧号 | |
next_keyframe | 该字段下一个关键帧的帧号 | |
active_keyframe_value | 该字段当前活动关键帧设置的值。相当于 S (阶跃插值)。 | |
next_keyframe_value | 该字段下一个关键帧设置的值 | |
prev_computed_value | 该字段在前一帧计算的值,或在第一帧为0。 | |
last_frame | 在“最终帧”输入字段中设置的值。类似于deforum中的“max_f”变量。 |
常量
常量 | 描述 | 示例 |
---|---|---|
PI | 常量π。 | |
E | 常量e。 | |
SQRT2 | 2的平方根。 | |
SQRT1_2 | 2的平方根。 | |
LN2 | 2的自然对数。 | |
LN10 | 10的自然对数。 | |
LOG2E | e的以2为底的对数。 | |
LOG10E | e的以10为底的对数。 |
单位
单位可以附加到数值常量后,通过文档的FPS和BPM从帧转换为节拍/秒。这在指定振荡器的周期(或其他代表时间周期的事物)时特别有用。
单位 | 描述 | 示例 |
---|---|---|
f | (默认) 帧 | sin(p=10f) (等同于 sin(p=10) ) |
s | 秒 | sin(p=2s) |
b | 节拍 | sin(p=4b) |
单位转换函数
使用这些函数在帧、节拍和秒之间转换:
单位 | 函数 | 示例 |
---|---|---|
f2b(x) | 帧到节拍 | |
b2f(x) | 节拍到帧 | |
f2s(x) | 帧到秒 | |
s2f(x) | 秒到帧 |
振荡器函数
所有函数可以通过未命名参数(例如sin(10,2)
)或命名参数(例如sin(period=10, amplitude=2)
)调用。大多数参数都有长名称和短名称(例如sin(p=10, a=2)
)。
在下面的例子中,注意振荡器的幅度设置为字段的线性插值值(L
),从第0帧的初始值1
到第120帧的值0
。这就是振荡器幅度随时间减小的原因。
函数 | 描述 | 示例 |
---|---|---|
sin() | 正弦波振荡器。见下文参数(仅周期是必需的)。 | |
sq() | 方波振荡器 | |
tri() | 三角波振荡器。 | |
saw() | 锯齿波振荡器。 | |
pulse() | 脉冲波振荡器。 |
振荡器参数:
- 周期
p
必需: 振荡的周期。默认单位是帧,但您可以通过添加适当的后缀指定秒或节拍(例如sin(p=4b)
或sin(p=5s)
)。 - 幅度
a
(默认值:1
):振荡的幅度。sin(p=4b, a=2)
等同于sin(p=4b)*2
。 - 相移
ps
(默认值:0
):振荡的x轴偏移量,即从帧号中减去多少以获得该帧的振荡x位置。有用的值是-active_keyframe
,这将使周期从关键帧位置开始。见下文示意图。 - 中心
c
(默认值:0
):振荡的y轴偏移量。sin(p=4b, c=2)
等同于sin(p=4b)+2
。 - 限制
li
(默认值:0
): 如果 >0,限制重复的周期数。 - 脉冲宽度
pw
(默认值:5
):仅pulse()函数 脉冲宽度。
示例:
使用sin(p=2b, a=L) 定义一个幅度线性增加的正弦波,意思是幅度是关键帧值的线性插值。 | |
在每个关键帧处限制为1个周期,使用li=1 。注意相对于完整正弦波保持相位,因此周期不会从关键帧开始。 | |
将相移设置为关键帧的负偏移量,使用ps=-active_keyframe ,可以确保周期从关键帧点开始。 |
过渡函数
功能 | 描述 | 示例 |
---|---|---|
`bez()` | 在前一个和下一个关键帧之间绘制贝塞尔曲线。所有参数都是可选的:
| |
`slide()` | 在线性滑动。在固定时间段内滑动。需要至少一个 `to` 或 `from` 参数(如果缺失则使用帧值),`in` 参数定义滑动持续时间。可选值 `os` 的行为类似于 `bez()` 的偏移量。参见图片中的3个示例。 |
噪声函数
功能 | 描述 | 示例 |
---|---|---|
rand() | 返回在 min 和 max 之间的随机数(默认0和1),使用种子 s (默认当前时间使用高精度计时器),保持该值的 'h' 帧(默认1)。参见图片中的3个示例。prompt_weight_1 每帧在0和1之间变换值,并且每次渲染时都会获得一组新值。prompt_weight_2 每40帧获取一个新的在1和2之间的随机值,并且每次渲染时也会获得一组新值。prompt_weight_3 每一拍获取一个新的在2和3之间的随机值,并且在每次渲染时使用相同的一系列值。 | |
smrand() | 平滑随机函数(simplex 噪声)。参数有平滑因子 sm (较大的值意味着更平滑的噪声,默认10),min (默认0),max (默认1)和种子 s (默认当前时间使用高精度计时器)。由于 simplex 本质上是一个 >2D 噪声生成算法,还存在一个 y 参数(默认0),你可以增加它(比如0.05),以稍微改变整体的噪声模式。 | |
perlin() | 类似于 smrand() ,但使用 perlin 算法代替 simplex。 | |
vibe() | 在随机间隔处绘制点,并在它们之间绘制贝塞尔曲线。取 min 和 max 定义值范围(默认 0, 1),pmin 和 pmax 定义点之间的帧数间隔范围(默认:1, 20),或使用 p 覆盖 pmin 和 pmax 为相同值,随机种子 s (默认当前时间使用高精度计时器),以及 c 或 x1,y1,x2,y2 定义贝塞尔曲线的形状(参见 bez() 上文)。 |
数学函数
功能 | 描述 | 示例 |
---|---|---|
min() | 返回两个参数中的最小值 | |
max() | 返回两个参数中的最大值 | |
abs() | 返回参数的绝对值 | |
round() | 返回参数的四舍五入值。第二个参数指定精度(默认: 0)。 | |
floor() | 返回取整后的参数值。第二个参数指定精度(默认: 0)。 | |
ceil() | 返回向上取整后的参数值。第二个参数指定精度(默认: 0)。 |
Javascript 数学函数
以下是暴露的一系列来自 Javascript Math 对象 的方法,以 _
为前缀。
注意,不像上面的 sin()
振荡器,这些函数并不是振荡器,它们只是简单的函数。
功能 | 描述 | 示例 |
---|---|---|
_acos() | 相当于 Javascript 的 Math.acos() | |
_acosh() | 相当于 Javascript 的 Math.acosh() | |
_asin() | 相当于 Javascript 的 Math.asin() | |
_asinh() | 相当于 Javascript 的 Math.asinh() | |
_atan() | 相当于 Javascript 的 Math.atan() | |
_atanh() | 相当于 Javascript 的 Math.atanh() | |
_cbrt() | 相当于 Javascript 的 Math.cbrt() | |
_clz32() | 相当于 Javascript 的 Math.clz32() | |
_cos() | 相当于 Javascript 的 Math.cos() | |
_cosh() | 相当于 Javascript 的 Math.cosh() | |
_exp() | 相当于 Javascript 的 Math.exp() | |
_expm1() | 相当于 Javascript 的 Math.expm1() | |
_log() | 相当于 Javascript 的 Math.log() | |
_log10() | 相当于 Javascript 的 Math.log10() | |
_log1p() | 相当于 Javascript 的 Math.log1p() | |
_log2() | 相当于 Javascript 的 Math.log2() | |
_sign() | 相当于 Javascript 的 Math.sign() | |
_sinh() | 相当于 Javascript 的 Math.sinh() | |
_sqrt() | 相当于 Javascript 的 Math.sqrt() | |
_tan() | 相当于 Javascript 的 Math.tan() | |
_tanh() | 相当于 Javascript 的 Math.tanh() | |
_sin() | 相当于 Javascript 的 Math.sin() |
信息文本匹配函数
所有关键帧都有一个可选的“信息”字段,该字段可以包含任意字符串。你可以在表达式中查询这些字段。例如,你可以使用函数检查当前关键帧的文本是否符合正则表达式,或计算过去包含某个子字符串的关键帧数量,或展望下一个包含给定字符串的关键帧何时出现。 <SOURCE_TEXT>
function | description | example |
---|---|---|
info_match() | 接受一个正则表达式作为参数。如果当前活动关键帧的信息标签与正则表达式匹配,则返回1,否则返回0。 | |
info_match_count() | 接受一个正则表达式作为参数。返回信息标签到目前为止匹配正则表达式的关键帧数量。 | |
info_match_last() | 接受一个正则表达式作为参数。返回匹配正则表达式的前一个关键帧的帧编号,如果当前帧是匹配关键帧,则返回当前帧编号,如果没有匹配,则返回-1。 | |
info_match_next() | 接受一个正则表达式作为参数。返回匹配正则表达式的下一个关键帧的帧编号,如果没有匹配,则返回-1。 |
提示操控函数
提示可以包括任何 Parseq 表达式。例如,以下是一个包含条件操作符 :
和字符串连接 +
的有效提示:
一幅画
${
如果 (f<10)
"一只猫":prompt_weight_1
否则
"一只狗":prompt_weight_2 + "有垂耳朵"
}
,非常详细
在帧数少于10的情况下,它会生成类似于一幅(一只猫:0.45)的画,非常详细
这样的提示,而在帧数为10及其以上时,它会生成一幅(一只狗:0.45)有垂耳朵的画,非常详细
。
请注意,如果您想确保生成图像中不会出现某物,通常在正提示中给它一个负权重是不够的:您需要将该术语放在负提示中。因此,如果您想让某物出现然后消失,就有必要在正提示和负提示之间“移动”它。可以通过条件语句来完成此操作,但以下函数使其变得更容易。
function | description | example |
---|---|---|
posneg(<term>, <weight>) | <term> 必须评估为字符串,<weight> 必须评估为数字。根据权重,在正提示和负提示之间自动切换术语。例如,如果 posneg("猫", prompt_weight_1) 在正提示中,那么 prompt_weight_1 为正的帧中会在正提示中包含 (猫:abs(prompt_weight_1)),而在 prompt_weight_1 为负的帧中会在负提示中包含 (猫:abs(prompt_weight_1))。 | 请参见这个 YouTube 示例视频。视频描述中包含 Parseq 文档的链接。 |
posneg_lora(<lora_name>, <weight>) | 同上,但适用于 loras。 posneg("Smoke", prompt_weight_1) 评估为 <"lora":"Smoke":prompt_weight_1> | 请参见这个 YouTube 示例视频。视频描述中包含 Parseq 文档的链接。 |
请参见上面的 :
操作符。
与时间和节拍(音频同步)一起工作
Parseq 提供一系列功能,帮助您创建具有精确定时参数波动的动画,例如用于音乐同步。
每分钟节拍数和每秒帧数
Parseq 允许您指定每秒帧数(FPS)和每分钟节拍数(BPM),用于将帧编号映射到时间和节拍偏移量。例如,如果您将FPS 设置为10,将 BPM 设置为120,当您将鼠标悬停在第 40 帧(在网格或图形中)上时,会显示该帧将出现在视频的4秒或8节拍内。
此外,您的插值公式可以使用 b 和 s 后缀引用节拍和秒。例如,这里我们定义了一个周期为1拍的正弦波振荡器(绿色),以及一个周期为5秒且脉冲宽度为0.5秒的脉冲振荡器(灰色):
将关键帧锁定到节拍或秒数
默认情况下,关键帧的位置是根据它们的帧编号来定义的,即使FPS 或 BPM 发生变化,帧编号也会保持不变。例如,如果您以10fps 开始,并在120 BPM 音轨的第4 节拍上创建一个关键帧,关键帧将在第20 帧处。但如果您决定将FPS 更改为20,并将音轨更新为140 BPM,您的动画将会失去同步,因为第4 节拍现在应该位于第34 帧上!
为了解决这个问题,您可以将关键帧锁定到它们的节拍(或秒)位置。完成此操作后,即使您更改FPS 或 BPM,它们也会保持同步。
定间隔创建关键帧
您可以使用“在间隔”选项卡快速创建与常规事件对齐的关键帧。例如,这里我们在前8 个节拍的每个节拍位置创建一个关键帧。关键帧位置将根据文档的 BPM 和FPS 进行确定。请注意,只有6 个关键帧会被创建,因为第0 和第 4 拍已经存在关键帧:
关键帧标记
一个常见的做法是标记关键帧以指示它们代表的音频事件(例如“低音鼓”、“军鼓”等)。然后您可以在插值公式中引用所有这些关键帧,例如 info_match_last()
、info_match_next()
和 info_match_count()
函数,以及批量编辑对话框中。
音频参考
为了帮助您对齐关键帧和公式与音频,您可以加载音频文件以在参数图旁边查看其波形。缩放和平移图表将应用于音频(单击并拖动以平移,按住alt/option键并用鼠标滚轮缩放)。滚动音频将会平移图表。图表和音频之间提供了视口控件。在两个可视化上显示了提示、节拍和光标标记。
https://user-images.githubusercontent.com/74455/228865210-be0a3202-3c9e-4037-8d9f-cd5bb3c8fd65.mp4
从音频事件自动生成关键帧
手动创建和标记音频事件的关键帧可能很繁琐。Parseq 通过使用 AubioJS 的音频事件检测功能改进了这一点:
加载参考音频文件后,转到波形下的事件检测选项卡并点击检测事件。标记将在波形上表示检测到的事件位置。
您可以通过控制以下选项来调整事件检测结果:
- 过滤:波形上方和右侧是一个二阶滤波器,允许您对音频应用低通/带通/高通滤波。例如,这将使您能够将低音鼓与军鼓分离。
- 方法:可选择一系列事件检测算法。请尝试这些方法,因为它们可能会产生截然不同的结果。有关详细信息,请参见 aubioonset CLI 文档。
- 阈值:定义在识别开始事件时的挑剔程度。阈值越低,事件越多,值越高,事件越少。
- 静音:从 aubio 文档中:"在其中不会检测到开始事件的音量,以 dB 为单位。-20.0 的值将消除大部分开始事件,但保留最响的开始事件。-90.0 的值将选择所有开始事件。"
一旦您对检测到的事件满意,可以切换到关键帧生成选项卡来创建关键帧。您可以选择一个自定义标签,这将分配给所有新生成的关键帧。如果某个位置已经存在关键帧,该标签将与现有标签组合。
请在 此教程 中观看事件检测和关键帧生成的实际操作。
使用时间序列进行音高和振幅同步
时间序列是 Parseq 的一个强大功能,允许您导入任何一系列数字,并在 Parseq 公式中引用它们。一个主要应用场景是将参数变化与音频音高或振幅同步。
点击“添加时间序列”并选择要处理的音频文件。然后您可以选择提取音高或振幅。当提取音高时,您可以从一系列方法中进行选择(有关详细信息,请参见 aubiopitch CLI 文档)。
提供了一个二阶滤波器,允许您在执行音高/振幅提取之前对音频进行预处理。
在提取数据后,您可以对其进行后处理,如取绝对值、排除在给定范围之外的数据点、钳制在给定范围之外的数据点,并归一化到目标范围。
使用绝对值对于振幅特别有价值,因为未处理的振幅将在正负之间振荡。
最终的时间序列将减少到最大 2000 点。绿色点表示帧落在这些点上。
一旦时间序列被创建,您可以为其选择一个别名,然后在公式中引用它们。
有两种引用时间序列的方法:方法 | 描述 | 示例 |
---|---|---|
timeseries_name | 返回当前帧的时间序列值,相当于 timeseries_name(f) | 复制的时间序列: |
timeseries_name(n) | 返回帧 n 的时间序列值 | 重复前10帧时间序列: |
请在此教程中查看音高检测的实际应用。
旧版音频分析工具
此功能已被弃用。请参见其在Parseq wiki上的存档文档。
任意数据序列的时间序列
除了音频音高和振幅数据之外,您还可以将任何CSV文件加载为时间序列。这意味着您可以导入几乎任何数列以在Parseq中使用。
CSV文件的格式必须是 timestamp,value
。在导入之前,您可以选择时间戳表示毫秒或帧。
例如,这里我们导入了ChatGPT 4生成的数据,询问后得到如下结果:
请生成格式为 x,y 的CSV输出,其中x从0到100递增1,y值绘制一个简单的城市天际线。仅输出CSV数据,请勿提供任何解释。
相机移动预览
Parseq有一个实验性功能,可以实时可视化您的相机移动。它受到@pharmapsychotic的AnimationPreview的启发。
目前,该功能有一些限制:
- 仅为粗略参考:图像变形算法与Deforum的不同。
- 目前仅适用于3D动画参数 (x, y, z translation 和 3d rotation)。
- 未考虑FPS或透视参数(fov, near, far)。
尽管如此,它对于了解运动参数的一般效果还是相当有用的:
https://github.com/rewbs/sd-parseq/assets/74455/03a18a78-e804-4e90-a061-1d9c1d063564
Deforum集成功能
Parseq可以与 所有 Deforum动画模式(2D、3D、prompt插值、视频等)一起使用。您无需在Parseq中做任何特别设置即可在模式之间切换:只需调整您感兴趣的参数。
可关键帧化的参数
以下是Parseq可以控制的参数。您可以在“管理字段”部分选择哪些参数由您的文档控制。任何在A1111 Deforum界面中设置了值且在“管理字段”中选择的字段将被Parseq覆盖。而未选择的字段可以继续在Deforum界面中控制。因此,您可以将Parseq控制的值与Deforum控制的值“混合匹配”。
稳定扩散生成参数:
- 种子
- 规模 (CFG)
- 噪声:在生成期间添加的额外噪声,可能有帮助
- 强度:上一帧生成的图像对当前生成的影响程度
2D动画参数:
- 角度(在3D动画模式中忽略,使用3D z轴旋转)
- 缩放(在3D动画模式中忽略,使用z轴平移)
- x轴平移
- y轴平移
伪3D动画参数(在3D动画模式中忽略):
- 透视θ角
- 透视φ角
- 透视γ角
- 透视视野
3D动画参数(在2D动画模式中全被忽略):
- z轴平移
- 3D x轴旋转
- 3D y轴旋转
- 3D z轴旋转
- 视野
- 最近点
- 远点
防模糊参数:
- 防模糊内核
- 防模糊sigma
- 防模糊量
- 防模糊阈值
混合视频参数:
- 混合合成alpha
- 混合合成掩码混合alpha
- 混合合成掩码对比度
- 混合合成掩码自动对比度低切
- 混合合成掩码自动对比度高切
其他参数:
- 对比度:调整上一帧生成图像对比度的因子,在馈送到当前生成时。1表示未改变,<1降低对比度,>1增加对比度。
提示操控
Parseq提供了另外8个可关键帧化参数(prompt_weight_1
到prompt_weight_8
),您可以在提示中引用,因此可以用作提示权重。您可以使用任何a1111识别的提示格式,记住${...}内的任何内容都会被当作Parseq表达式进行计算。
例如,以下是一个使用可组合扩散在面部之间插值的正面提示:
Jennifer Aniston, centered, high detail studio photo portrait :${prompt_weight_1} AND
Brad Pitt, centered, high detail studio photo portrait :${prompt_weight_2} AND
Ben Affleck, centered, high detail studio photo portrait :${prompt_weight_3} AND
Gwyneth Paltrow, centered, high detail studio photo portrait :${prompt_weight_4} AND
Zac Efron, centered, high detail :${prompt_weight_5} AND
Clint Eastwood, centered, high detail studio photo portrait :${prompt_weight_6} AND
Jennifer Lawrence, centered, high detail studio photo portrait :${prompt_weight_7} AND
Jude Law, centered, high detail studio photo portrait :${prompt_weight_8}
以下是一个使用术语加权的示例:
(Jennifer Aniston:${prompt_weight_1}), (Brad Pitt:${prompt_weight_2}), (Ben Affleck:${prompt_weight_3}), (Gwyneth Paltrow:${prompt_weight_4}), (Zac Efron:${prompt_weight_5}), (Clint Eastwood:${prompt_weight_6}), (Jennifer Lawrence:${prompt_weight_7}), (Jude Law:${prompt_weight_8}), centered, high detail studio photo portrait
对应的参数流可能是这样的:
注意,任何Parseq表达式都可以使用,例如以下将在每次节拍时在猫和狗之间交替:
Detailed photo of a ${if (floor(b%2)==0) "cat" else "dog"}
一些重要提示:
- 请记住,除非您将“强度”设置为0,否则前一帧将影响当前帧,除了提示之外,即使在给定帧上从提示中移除,之前的物项也不会立即消失。
- 为了抵消这一点,您可能希望将您希望在给定帧上_不_出现的术语也放在负面提示中,并反转权重。
所以之前的例子可能是这样的:
正面提示 | 负面提示 |
---|---|
Detailed photo of a ${if (floor(b%2)==0) "cat" else "dog"} | ${if (floor(b%2)==0) "dog" else "cat"} |
使用多个提示
您可以添加附加提示并将每个提示分配给一个帧范围:
如果范围重叠,Parseq将使用可组合扩散 结合重叠的提示。您可以决定可组合扩散权重是固定的、线性滑入和滑出,还是由自定义Parseq表达式定义的。
注意,如果重叠的提示已经使用了可组合扩散(... AND ...
),这可能会导致意外结果,因为只有原始提示的最后一部分会与重叠提示加权。Parseq会警告您如果出现这种情况。
子种子控制种子旅行
有关种子旅行的详细说明,请参见Yownas的脚本。简而言之,您可以通过设置第一个种子作为(主)种子,第二个种子作为子种子,并波动子种子强度,在两个种子生成的潜在噪声之间插值。子种子强度为0只会使用主种子,而1则只会使用子种子作为种子。介于两者之间的任何值都会使用球面线性插值(SLERP)在两种噪声模式之间插值。
Parseq目前没有显式暴露子种子和子种子强度参数。相反,它使用分数种子值来控制子种子和子种子强度值。例如,如果在给定帧上的种子值为 10.5
,Parseq将发送 10
作为种子,11
作为子种子和 0.5
作为子种子强度。
缺点是您只能在相邻种子之间插值。好处是种子旅行非常直观。如果您希望完全控制子种子和子种子强度,请随时提出功能请求!
请注意,种子旅行的效果在没有输入图像(插值动画模式)或强度非常低的情况下效果最佳。否则,输入的低变化可能会导致伪影/深度油炸。
否则最好在每帧上至少更改1个种子(您也可以尝试种子振荡,以减少变化)。
增量值(即绝对vs相对运动参数)
Parseq旨在让您为所有参数设置绝对值。 因此,如果您想在4帧内逐步旋转180度,您需要为每帧指定以下值:45、90、135、180。
然而,由于稳定扩散动画是通过将上一帧生成的图像馈送到当前生成步骤中,因此某些动画参数变得相对的,如果有足够的回环强度。因此,如果您想在4帧内旋转180度,动画引擎期望的值分别是:45、45、45、45。
这并不是所有参数的情况:例如,种子值和视野设置不依赖于之前的帧,因此动画引擎期望的是绝对值。
为了解决这个问题,Parseq为某些参数提供_增量值_给Deforum。默认情况下是启用的,但您可以在A111 Deforum扩展UI中将其关闭以查看不同。
对于大多数参数,给定字段的增量值只是该字段的当前值与上一帧值之间的差异。然而,某些参数如2D缩放(实际是一个比例因子)是乘法值,因此增量是前后值之比。
处理大量帧(性能提示)
Parseq在处理大量帧时可能会变慢。如果您看到性能下降,请尝试以下操作: 在管理字段部分,只选择你想用Parseq控制的字段。 关闭你不使用的部分。例如,如果你不使用Sparklines或测试输出视图,使用部分标题旁边的^关闭它们。 通过在"显示/隐藏字段"选择框中取消选择不活跃使用的字段来隐藏它们(或通过点击它们的小波形图来切换它们)。 禁用自动渲染(并记得在每次更改后手动点击渲染按钮)。 注意,当显示超过1000帧时,图形将变得不可编辑,并且不会显示关键帧。要恢复编辑,请缩小到小于1000帧的部分。
开发和本地运行
Parseq目前是一个前端React应用。它正在从Javascript转换为Typescript的过程中。目前后端非常少:默认情况下,持久性完全在浏览器indexdb存储中通过Dexie.js实现。登录用户可以选择将数据上传到Firebase支持的数据存储。
在开始之前,你需要在系统上安装node
和npm
。
如果你想深入了解:
- 运行
npm install
以拉取依赖项。 - 运行
npm start
以在本地以开发模式在3000端口运行Parseq UI。你现在可以在localhost:3000
上访问UI。代码更改应自动热重载。
部署
托管和部署使用Firebase。合并到master分支会自动部署到暂存通道。PR会自动部署到开发通道。目前没有自动的部署后验证或提升到生产环境。
假设你有正确的权限,你可以查看活动部署:
firebase hosting:channel:list
并从暂存环境提升到生产环境:
firebase hosting:clone sd-parseq:staging sd-parseq:live
致谢
该脚本包括来自许多其他脚本的想法和代码。特别感谢以下支持和灵感来源:
- 感谢所有在Parseq上通过Patreon支持我的人,包括:Adam Sinclair, MJ, AndyXT, King Kush, Ben Del Vacchio, Zirteq, Kewk, BinaryLady at TheTechMargin, ascendant, Sasha Agafonoff, Brandon Glasgow, Koshi Mazaki, lexvesseur, Andreas Lewitzki, veryVANYA, Nenad Kuzmanovic, Stash, Sinneys, wildpusa, Chris Hughes, Desmond Grealy, HackerPrime, Lottery Discountz, Ronny Khalil
- 感谢所有请我喝咖啡的人!
- 感谢所有为A1111 web UI做出贡献的人
- 感谢所有为Deforum做出贡献的人
- 感谢所有尝试Parseq并在Discord上反馈的人
- 感谢Aubio, AubioJS, Wavesurfer, react-timeline-editor, ag-grid(社区版),p5, chart.js和recharts背后的人。
- 以下脚本及其作者,当我刚开始时,从中吸取了一些好主意:
- 感谢Filarus的vid2vid脚本.
- 感谢Animator-Anon的动画脚本。
- 感谢Yownas的种子旅行脚本
- 感谢feffy380的prompt-morph脚本
- 感谢eborboihuc的【3d旋转实现】 使用
cv2.warpPerspective()
(https://github.com/eborboihuc/rotate_3d/blob/master/image_transformer.py)