仓库源文站点原文

本文是Stable Diffusion系列第三篇。

前两篇文章我们介绍了在本地运行Stable Diffusion模型的方法,以及使用LoRA对模型生成的图片进行微调。

本篇文章中,我们将介绍两种技术来控制图像的生成过程,对模型图像生成进行引导,使得生成的图像更符合我们的需求。这样生成的图片,更具有商业价值。

图像生成引导技术

Stable Diffusion等文本转图像模型中,"对模型图像生成进行引导"是指通过提供额外的信息来控制图像生成过程,使其生成更符合预期的图像。引导的方法有多种,比如前两篇文章提及的“引导词”和LoRA都是引导技术的一种。在本篇文章中,重点介绍的是“使用参考图像”进行引导的方法,也就是Image to Image。试想一下:你先用草稿将绘画元素勾勒出来,然后利用该技术即可让AI对作品细节进行补充。

ControlNetAdapter

这个表格展示了这两种技术的工作原理及优缺点:

特性 Adapter ControlNet
工作原理 基于提示嵌入 基于神经网络
优点 易于使用、灵活 效果好、可控性强
缺点 效果可能不佳、需要额外的训练数据 使用复杂、需要训练数据

controlnet-aux

在开始前,我们先下载一个工具:

pip install controlnet-aux mediapipe

controlnet-aux提供了多种辅助模型,称为Detector。这些 Detector可以分析图像并提取特定的信息,然后将这些信息作为条件传递给 ControlNet,从而更精细地控制图像生成过程。这一步骤我们称之为生成“引导图”。以下是一些常见的Detector模型及其简介:

要使用这些Detector,需要先下载模型,地址:https://huggingface.co/lllyasviel/Annotators。你需要哪些Detector就下载哪些模型。省事的话就全部下载。

各种Detector对比

首先写一段代码运行Detector

from controlnet_aux import HEDdetector
from diffusers.utils import load_image, make_image_grid

device = 'mps'
original_image = load_image("data/3.jpg")
hed = HEDdetector.from_pretrained("your/path/controlnet-annotators").to(device)

hed_image = hed(original_image)
image_grid = make_image_grid([original_image, hed_image], rows=1, cols=2)
image_grid.save("data/out.jpg")

代码很简单,就不做解释了,下面是各种Detector的效果演示:

各种Controlnet对比

以上我们使用Detector生成了各种“引导图”,接下来我们使用Controlnet对引导图进行创作。老规矩,先去hugging face下载模型,我们这次测试的Controlnet都是sdxl的,具体原因参考前两篇文章:

编写代码:

from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel, DPMSolverSinglestepScheduler
from diffusers.utils import load_image, make_image_grid
from controlnet_aux import CannyDetector


device = 'mps'
original_image = load_image("data/3.jpg")
canny = CannyDetector()
canny_image = canny(original_image)

controlnet = ControlNetModel.from_pretrained(
    "your/path/controlnet-canny-sdxl-1.0",
    use_safetensors=True
)

pipe = StableDiffusionXLControlNetPipeline.from_single_file(
    "your/path/dreamshaperXL_v21TurboDPMSDE.safetensors",
    controlnet=controlnet,
    use_safetensors=True
).to(device)
pipe.scheduler = DPMSolverSinglestepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
# pipe.enable_model_cpu_offload()

prompt = "masterpiece, 1girl, long hair, asian, sundress, cartoon"
negative_prompt = 'low quality, bad quality, sketches'

image = pipe(
    prompt,
    negative_prompt=negative_prompt,
    image=canny_image,
    # controlnet_conditioning_scale=0.5,
    height=1024,
    width=576,
    num_inference_steps=6,
    guidance_scale=2,
).images[0]
image_grid = make_image_grid([original_image, image], rows=1, cols=2)
image_grid.save("data/out.jpg")

提示词与上一篇文章一模一样,让我们来看一下生成的图片。

各种Adapter对比

Contronet一样,先去hugging face上下载模型,这次我们使用腾讯的t2i-adapter进行测试:

编写代码:

from diffusers import T2IAdapter, StableDiffusionXLAdapterPipeline, DPMSolverSinglestepScheduler
from diffusers.utils import load_image, make_image_grid
from controlnet_aux import CannyDetector

device = 'mps'
original_image = load_image("data/3.jpg")
canny = CannyDetector()
canny_image = canny(original_image)

adapter = T2IAdapter.from_pretrained("your/path/t2i-adapter-canny-sdxl-1.0")

pipe = StableDiffusionXLAdapterPipeline.from_single_file(
    "your/path/dreamshaperXL_v21TurboDPMSDE.safetensors",
    # controlnet=controlnet,
    adapter=adapter,
    use_safetensors=True
).to(device)
pipe.scheduler = DPMSolverSinglestepScheduler.from_config(pipe.scheduler.config, use_karras_sigmas=True)
# pipe.enable_model_cpu_offload()

prompt = "masterpiece, 1girl, long hair, asian, sundress, cartoon"
negative_prompt = 'low quality, bad quality, sketches'

image = pipe(
    prompt=prompt,
    negative_prompt=negative_prompt,
    image=canny_image,
    # controlnet_conditioning_scale=0.5,
    height=1024,
    width=576,
    num_inference_steps=6,
    guidance_scale=2,
).images[0]
image_grid = make_image_grid([original_image, image], rows=1, cols=2)
image_grid.save("data/out.jpg")

总结

从图片质量可以看出,ControlNet对于引导图的遵循和生成图片的质量都较Adapter高,具体使用情况如何,大家在使用前还是自己测试一下。