你是否遇到过想在一张图片的左上角绘制一个太阳,右上角绘制一些云朵,在下方在绘制其他的…,常规方式通过提示词,我们会发现图像大多情况不受我们控制,不会一定按我们的方式去绘制成功。
今天给大家介绍一个插件,可通过设置提示词就能精准实现按区域绘图,就可以实现上面说的按我们自己的方式精准控制去绘图。
Regional Prompter
插件:Regional Prompter
地址:https://github.com/hako-mikan/sd-webui-regional-prompter
注意:该插件是针对Stable Diffusion Web UI的。
插件的安装这里就不过多介绍了,可以参考之前的文章————Stable Diffusion Web UI基础插件推荐。
下面我们通过一个简单的例子来说明 Regional Prompter 插件的用法。为演示效果,我们先用非常简单的提示词试试。
假设你想在同一张图片中生成一个男人和一个女人。我们使用简单的提示:
a man and a woman
负提示词如下:
disfigured, ugly
其他我们都使用默认参数。
然后我们获得如下图片:
看起来都没啥问题。但是如果你想更具体一点呢?比如生成一个黑头发的男人和一个金发女人?当然,我们可以在提示中写出来。
a man with black hair, a woman with blonde hair
你有时会得到你所描述的,但也有时候,Stable Diffusion 会混淆哪种头发颜色应该与谁搭配。如果你想进一步指定衣服的颜色等,情况将更加困难。
那么,这到底是咋回事呢?为什么这么简单的事情,Stable Diffusion 都做不到呢?这是因为 self-attention 机制将头发颜色和人物错误关联了。
此问题有一个解决方案:将黑发男子的提示词仅指定到图像左侧,而金发女郎的提示词则指定到图像右侧。
这个时候我们就可以使用Regional Prompter
插件了。
1、在文生图(txt2img) 标签页中展开 Regional Prompter。
2、选中 Active 来激活分区域的提示器。
3、其他的保持默认设置,基本当前的示例足够了。在检查下面的设置:
- Main Splitting: Columns(按列分割)
- Divide Ratio: 1, 1
- Width and Height: 这个必须和文生图(txt2img)匹配
4、点击visualize and make template
按钮,我们能看到图片被分为两个区域:区域0在左侧,区域1在右侧。同时它们按1比1比例平均分割。
5、更新为如下提示词
a man and a woman, a man with black hair
BREAK
a man and a woman, a woman with blonde hair
BREAK
关键字分隔了提示词。上面我们有两个提示。第一个提示将应用于区域0。第二个提示将应用于区域1。
负提示词:
disfigured, deformed, ugly
在负提示词中没有BREAK
,所以这个提示词将作用到所有区域(即上面的两个区域都会生效)。
点击生成,我们得到如下效果图:
Stable Diffusion 会在区域 0 (左侧)生成一名黑发男子,在区域 1(右侧)生成一名金发女子。
请注意,这并非 100% 有效。根据我的经验,只有 75% 的成功率。但依然比完全靠运气要好得多。
通用提示词(Common prompt)
你可能已经注意到这两个提示有一个共同的部分“一个男人和一个女人”。
a man and a woman, a man with black hair
BREAK
a man and a woman, a woman with blonde hair
为什么需要通用提示?如果没有通用提示,Stable Diffusion只会生成一个人:
a man with black hair
BREAK
a woman with blonde hair
为什么?左右区域的提示都描述了一个人。所以你得到…一个人!你需要告诉 Stable Diffusion 这是一张两个人的照片:一个男人和一个女人。
这就是为什么你需要一个常见的提示,“一个男人和一个女人”。
当然,这个示例只是搞得玩的。而真实场景下生图的提示词通常是很长的。长提示词下处理公共提示词,有更方便的办法:
1、勾选使用通用提示选项(Use common prompt
)。
2、现在就可以在提示词的开头加上公共提示词(a man and a woman):
a man and a woman
BREAK
a man with black hair
BREAK
a woman with blonde hair
上面我们就有三个提示词:
(1)公共提示词;
(2)区域 0 的提示词;
(3)区域 1 的提示词。
公共提示词会被添加到每个区域的提示词开头。
其实吧,公共提示词就只是一个语法糖:等同于原始提示词中的内容。
a man and a woman, a man with black hair
BREAK
a man and a woman, a woman with blonde hair
效果如上相同:
复杂的区域
使用 Regional Prompter 的秘诀就是准确定义区域。在本节,我会解释如何设置分割比(divide ratio) ,从而以我们想要的方式来拆分图像。如何正确指定区域可能很难理解或者难记,所以你可以点击 Visualize and make template(可视化并生成模板) 来生成并确定区域图。
一维
在一维划分中,可以水平或垂直划分区域。
水平分割(Horizontal division)
分割比的样例:
1,1
1,1,1
1,2,1
垂直划分(Vertical division)
行(垂直)分割类似,只是区域是按行划分的。以下是一些划分比例的示例。
1,1
1,1,1
1,2,1
二维区域
您可以在同一幅图像中垂直和水平划分区域。选择列(Columns)分割。
规则如下
- 行用分号(;)分割。
- 每一行是用逗号分隔的一系列数字,比如 1,1,1。
- 每一行中的第一个数字代表行的高度,之后的数字代表区域的宽度。
我们来看一些例子:
1,1,1; 1,1,1
这定义了两行,每行高度为 1。两行都有两个宽度相等的区域 (1,1)。
总共有4个区域。
1,1,1; 2,1,1
- 这定义了两行。
- 第一行的高度为 1。
- 第二行的高度为 2。
- 每行有两个区域,宽度相等 (1,1)。
- 总共有 4 个区域。
最后我们来看一个更复杂的例子,理解了这个,你就理解了区域划分的所有内容!
1,1,1,1; 2,1,2
- 有两行。
- 第一行的高度为 1。
- 第二行的高度为 2。
- 第一行有 3 个区域,宽度为 1。(1,1,1) 第二行有两个区域,宽度分别为 1 和 2。(1,2)
- 总共有 5 个区域。
二维分区域提示词的示例
下面假设我们在尝试真正的图。我想出了下面的提示词。
模型:VisualNovel
提示词:
a witch, highly detailed face, half body, studio lighting, dramatic lighting, highly detailed clothing, looking at you, mysterious, dramatic lighting, (full moon:1.3), (beautiful fire magic: 1.2)
负提示词:
underage, immature, disfigured, deformed
点击生成,我们得到如下效果图:
还不错,但是无法控制月亮和火焰的位置。你所能做的就是不断点击“生成”按钮,直到得到你想要的位置。
这时Regional Prompter就可以提供帮助。 使用以下设置:
- Main Split: Columns
- Use common prompt: Yes
- Divide ratio: 1,1,1;2,1,1
使用如下提示词:
a witch, highly detailed face, half body, studio lighting, dramatic lighting, highly detailed clothing, looking at you, mysterious, dramatic lighting
BREAK
(full moon:1.3)
BREAK
BREAK
BREAK
(beautiful fire magic: 1.2)
这样就将月亮放在了区域 0(左上),将火焰放在了区域 3(右下)。如下图所示:
现在我们就能控制具体的位置情况了。
接着,我们把月亮放在右上方(区域 1),把火放在左下方(区域 2)。
a witch, highly detailed face, half body, studio lighting, dramatic lighting, highly detailed clothing, looking at you, mysterious, dramatic lighting
BREAK
BREAK
(full moon:1.3)
BREAK
(beautiful fire magic: 1.2)
BREAK
然后就可以看到生成的图中月亮出现在右上角,火出现在左下角,如下图所示。
同样的,你应该知道到区域提示词并非100%有效。因此,一次最好多生成几张图片。
区域提示词(Regional Prompter)和ControlNet配合使用
区域提示器(Regional Prompter)可以指定每个区域的提示,但是它不能控制整个图像构图。不过,有个工具可以做到这一点。这个工具就是 ControlNet。
下面我们看两个例子。这两个例子配合使用 Regional Prompter 和 ControlNet,实现了我们在没有它们时只能梦想的操纵程度。
第一个例子:控制全局和局部构图
下面假设我们想生成一张图,图中是一个漂亮的女士在公园的座椅上读书。此外,还想让女士旁边有小猫,草地上放着书包。
提示词如下:
a beautiful lady regular certified reading,highly detailed face,highly detailed clothing BREAK a cat on the grass,cinematic,sun,clouds,park,in a meadow,chair,schoolbag,
负提示词:
underage,immature,disfigured,deformed,
我们可以看到这张图片其实还是比较接近我想象的图片的,但是我几乎无法控制女士的姿势以及放大到多近。
添加ControlNet
下一步是使用ControlNet控制姿势。我假设你已经安装了它并且了解基础知识。当然,后面关于ControlNet会单独做介绍。
我们通过这张图来控制姿势,参考图如下:
1、把参考图像上传到图像画布,也可以直接把参考图像拖拽过来。
2、勾选启用(Enable)。
3、在预处理器(Preprocessor)下拉菜单中选中 openpose。
4、在模型(Model)下拉菜单中选中 control_opepose 。
如果想查看图片提取的姿势,可按下面的步骤执行。
- 勾选“允许预览”。
- 模型下拉菜单旁边会出现一个类似爆炸的新图标。单击该图标即可预览姿势。
现在我们点击生成,就会使用 ControlNet 生成图像。如下:
现在我们控制了图片中人物的姿势,接着我们就可以通过Regional Prompter来控制其他描述。
添加分区域提示词(Regional Prompter)
我们使用水平分割模式(Horizontal Divide),勾选使用通用提示词(Use common prompt)。
1,1,1.5; 1,1,1.5
这 4 个区域就像下图这样:
我想控制整幅图像:
- 一名女士
- 区域 0:一些阳光下的云朵
- 区域 1:一名坐椅子女士读书的女士
- 区域 2:一只可爱的猫在草地上
- 区域 3:在草地上的书包
提示词如下:
a beautiful lady,highly detailed face,highly detailed clothing,
BREAK
some clouds under the sun,
BREAK
sit in a chair and read carefully,
BREAK
(1 cat sit the grass:1.5),
BREAK
(schoolbag on the grass:1.5),
注意,我增加了一些关键词的权重。否则,对象可能不会显示出来。
现在,你可以完全控制云朵、猫和书包的位置。参见下图。
第二个例子:正确的颜色分配
假设你想生成一些棕色头发、黄色上衣和蓝色裙子的女性照片。听起来很简单?
如果你尝试生成类似的东西,你就会知道这是一个挑战。
让我们看一下带有以下提示词的例子
full body photo of young woman, natural brown hair, yellow blouse, blue skirt, busy street, rim lighting, studio lighting, looking at the camera, dslr, ultra quality, sharp focus, tack sharp, dof, film grain, Fujifilm XT3, crystal clear, 8K UHD, highly detailed glossy eyes, high detailed skin, skin pores
disfigured, ugly, bad, immature, cartoon, anime, 3d, painting, b&w
你会发现 Stable Diffusion 在即兴发挥!颜色都混在一起了…
我们会看到,告诉 Stable Diffusion 哪种颜色应该放在哪里并非易事。提示词 token 的 self-attention 效果并不好。
可能偶尔颜色会正确分配,这里我们就可以可以使用 Regional Prompter 搞定。下面我们把图像垂直分成 3 个部分。
使用垂直分割(Rows)
1, 1, 1.5
更新提示词如下:
full body photo of young woman, busy street, rim lighting, studio lighting, looking at the camera, dslr, ultra quality, sharp focus, tack sharp, dof, film grain, Fujifilm XT3, crystal clear, 8K UHD, highly detailed glossy eyes, high detailed skin, skin pores
BREAK
natural brown hair
BREAK
(yellow blouse: 1.3)
BREAK
(blue skirt: 1.3)
负提示词:
disfigured, ugly, bad, immature, cartoon, anime, 3d, painting, b&w
非常好!区域提示是解决颜色分配问题的有效方法。
同时如果我们使用ControlNet对姿势可以获得更多控制。
创意探索
最后我们还可通过该插件创作一些新创意的图片。
如下的示例是把自然场景的一张图水平划分为四个部分,并为每个部分分配不同的天气
Divide mode: Horizontal
Divide ratio: 1,1,1,1
Use common prompt: Yes
提示词:
a beautiful wild park, path to freedom, courage and love, national geographic photo of the year
BREAK
spring, trees, birds, green grasses, (sunny, wild flowers:1.2), god ray, clear sky
BREAK
cloudy, dry
BREAK
thunderstorm, rain
BREAK
winter, heavy snow, barren trees
负提示词:
BREAK
snow
BREAK
BREAK
BREAK
BREAK
得到结果如下:
最后的提示
- 如果有东西看到不到,就增加关键词的权重。
- 得到一张不完美的图再正常不过了。用局部重绘(inpainting)到处修复一下。与很多其他插件不同,Regional Prompter 在文生图和图生图之间是共享设置的。所以,如果不想把 Regional Prompter 用于局部重绘,请务必取消选中 Active。
- 这个插件的功能比我这里讲的要多。请参见该插件的Regional Prompter页面了解更多信息。
原理
latent couple
Stable Diffusion中的Unet是UNet2DConditionModel,在常规的Unet的基础之上添加了cross attention,这里cross attention所耦合的信息就是所谓的condition,也就是prompt;而常规的Unet输入就是需要处理的图片(可以是图片,也可以是高斯噪声,也可以是图片与高斯噪声的叠加态)。
上图中所展示的latent couple过程就比较清晰,在这个示例中,生成的图片被分成了两个区域,分别用左区域和右区域来代替,latent couple在文生图中需要准备一个base prompt,也就是基础提示词,这个prompt的作用区域是全图范围的,该base prompt会生成一个base latent;然后左区域和右区域的prompt同样也要分别生成两个latent,暂时称之为左latent和右latent;然后将左latent与右latent按照之前划分好的区域进行组合拼接,最后将组合好的latent与base latent按照预设比例进行叠加,得到了我们想要的噪声,然后再按照我们预设的的采样方法就可以得到想要的图片了。
在这个过程中,我们将图片划分成了两个部分,然后在生成图片的过程中,Unet一共生成了3次latent。
attention couple
Attention Couple不会对每个提示计算UNet,而是对每个与提示相关的模块进行相同的计算。这样可以显着减少计算量。此外,由于耦合计算是在 UNet 内执行的,因此将生成更一致的图像(希望如此)。因此,基本提示可能不是必需的,但这次我们用基本提示来实现(根据设置,也可以重现没有基本提示的状态)。
latent couple如果将区域划分为2个区域,那么Unet会对不同的prompt计算3次,同时作者指出,Unet中并不是所有模块都直接和prompt相关,为了减少计算量,作者打算只对Unet中和prompt相关的模块进行重复计算;
查看latent diffusion的示意图,如下:
prompt经过text encoder转化后在图中就是τθ,然后在cross attention中,其只与q,k,v中的k,v有关(不理解可以看下源码),这样就只需要计算与prompt强相关的k,v,然后执行常规的transformer计算得到qkv,然后将生成二维矩阵按照prompt作用的区域拼接起来,由于这种作用的方式比较高维,或者说抽象(因为并不直接作用在latent上),所以这种方式可以不需要base prompt,直接分区域分别写prompt也可以生成连贯的图像。
今天的分享到此为止,欢迎大家关注微信公众号"壁虎说技术",更多AI新技术,新点子在公众号第一时间更新。
参考
regional-prompter
sd-webui-regional-prompter
Regional Prompter/latent couple/attention couple的原理
複数キャラクターを分けて生成するLatent coupleの改良版!(Attention Couple)
High-Resolution Image Synthesis with Latent Diffusion Models