欢迎光临
我们一直在努力

扩散模型进阶:ControlNet、IP-Adapter 与图像编辑

扩散模型进阶:ControlNet、IP-Adapter 与图像编辑

1. 引言

Stable Diffusion 的文生图能力已经非常强大,但"纯文字"控制往往不够精确。ControlNet 和 IP-Adapter 让我们能用边缘图、姿态图、参考图像来精确控制生成结果。

控制方式对比:

方法控制信号精度适用场景
Text-to-Image 文字 创意生成
ControlNet 结构图 建筑/姿态/深度
IP-Adapter 参考图像 风格/角色一致性
Inpainting 局部遮罩 局部编辑

2. ControlNet

2.1 原理

ControlNet 在 UNet 的编码器上添加旁路分支:

原始 UNet 编码器 → 下采样特征

ControlNet 旁路 → 条件特征(边缘/深度/姿态)

零卷积融合 → UNet 解码器

2.2 支持的控制类型

CONTROL_TYPES = {
"canny": "边缘检测图",
"depth": "深度图",
"pose": "人体姿态(OpenPose)",
"scribble": "涂鸦/草图",
"lineart": "线稿",
"mlsd": "直线检测(建筑)",
"normal": "法线图",
"seg": "语义分割图",
"shuffle": "内容随机打乱",
"tile": "超分辨率/细节增强",
"inpaint": "局部重绘",
"ip2p": "指令编辑",
"reference": "参考图",
}

2.3 使用 ControlNet

from diffusers import (
StableDiffusionXLControlNetPipeline,
ControlNetModel,
UniPCMultistepScheduler,
)
from controlnet_aux import CannyDetector
from PIL import Image
import torch

# 加载 ControlNet
controlnet = ControlNetModel.from_pretrained(
"diffusers/controlnet-canny-sdxl-1.0",
torch_dtype=torch.float16,
)

# 加载 Pipeline
pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=controlnet,
torch_dtype=torch.float16,
).to("cuda")

pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)

# 提取控制图
canny = CannyDetector()
image = Image.open("input.jpg")
control_image = canny(image, low_threshold=100, high_threshold=200)

# 生成
result = pipe(
prompt="a beautiful modern building, professional photography",
image=control_image,
num_inference_steps=30,
controlnet_conditioning_scale=0.7,
guidance_scale=7.5,
).images[0]

result.save("controlnet_output.jpg")

2.4 多 ControlNet 组合

# 同时使用 Canny + Depth
controlnet_canny = ControlNetModel.from_pretrained(
"diffusers/controlnet-canny-sdxl-1.0", torch_dtype=torch.float16
)
controlnet_depth = ControlNetModel.from_pretrained(
"diffusers/controlnet-depth-sdxl-1.0", torch_dtype=torch.float16
)

pipe = StableDiffusionXLControlNetPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
controlnet=[controlnet_canny, controlnet_depth],
torch_dtype=torch.float16,
).to("cuda")

result = pipe(
prompt="a modern living room",
image=[canny_image, depth_image],
controlnet_conditioning_scale=[0.5, 0.3], # 各自的权重
).images[0]

3. IP-Adapter

3.1 原理

IP-Adapter 将参考图像的特征注入到 UNet 的交叉注意力中:

参考图像 → CLIP 图像编码器 → 图像特征

UNet 交叉注意力 = Text特征 × Q + Image特征 × K' × V'

3.2 使用 IP-Adapter

from diffusers import StableDiffusionXLPipeline
from diffusers.utils import load_image
from ip_adapter import IPAdapterXL

# 加载
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
).to("cuda")

ip_adapter = IPAdapterXL(
pipe,
image_encoder_path="models/image_encoder",
ip_ckpt="models/ip-adapter_sdxl_vit-h.bin",
device="cuda",
)

# 参考图像
reference_image = load_image("character.jpg")

# 生成
result = ip_adapter.generate(
prompt="a girl in a park, sunny day",
pil_image=reference_image,
num_samples=1,
num_inference_steps=30,
scale=0.6, # IP-Adapter 强度
)[0]

result.save("ip_adapter_output.jpg")

3.3 IP-Adapter 强度控制

# scale 参数控制参考图像的影响程度
# 0.0 = 完全忽略参考图
# 1.0 = 强烈参考参考图
# 0.4-0.7 = 通常效果最好

for scale in [0.3, 0.5, 0.7, 0.9]:
result = ip_adapter.generate(
prompt="a man in a suit",
pil_image=reference_image,
scale=scale,
)[0]
result.save(f"scale_{scale}.jpg")

4. 图像编辑

4.1 Inpainting(局部重绘)

from diffusers import StableDiffusionXLInpaintPipeline

pipe = StableDiffusionXLInpaintPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
).to("cuda")

# 原图和遮罩
image = Image.open("original.jpg")
mask = Image.open("mask.png") # 白色区域=重绘区域

result = pipe(
prompt="a red sports car",
image=image,
mask_image=mask,
num_inference_steps=30,
strength=0.8, # 重绘强度
).images[0]

4.2 图像到图像(Img2Img)

from diffusers import StableDiffusionXLImg2ImgPipeline

pipe = StableDiffusionXLImg2ImgPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
).to("cuda")

original = Image.open("sketch.jpg")

result = pipe(
prompt="a detailed architectural rendering",
image=original,
strength=0.75, # 0=不变, 1=完全重绘
guidance_scale=7.5,
).images[0]

4.3 指令编辑(InstructPix2Pix)

from diffusers import StableDiffusionInstructPix2PixPipeline

pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(
"timothybrooks/instruct-pix2pix",
torch_dtype=torch.float16,
).to("cuda")

image = Image.open("photo.jpg")

# 用自然语言描述编辑操作
result = pipe(
prompt="make the sky sunset",
image=image,
image_guidance_scale=1.5, # 保持原图的程度
guidance_scale=7.5,
).images[0]

5. 一致性模型(Consistency Model)

5.1 原理

传统扩散模型:需要 20-50 步去噪
一致性模型:1-4 步即可生成

核心思想:学习一个函数,直接将噪声映射到干净图像

5.2 使用

from diffusers import ConsistencyModelPipeline

pipe = ConsistencyModelPipeline.from_pretrained(
"openai/diffusion-model-sdxl-1.0",
torch_dtype=torch.float16,
).to("cuda")

# 1-4 步生成
result = pipe(
prompt="a cat sitting on a windowsill",
num_inference_steps=4,
).images[0]

6. 总结

扩散模型进阶的核心技术:

  • ControlNet:用结构图(边缘/深度/姿态)精确控制生成
  • IP-Adapter:用参考图像控制风格和角色一致性
  • Inpainting:局部重绘,只修改图像的指定区域
  • 组合使用:ControlNet + IP-Adapter + LoRA = 精确可控生成
  • 一致性模型:1-4 步生成,速度提升 10 倍
  • 赞(0)
    未经允许不得转载:171主机测评 » 扩散模型进阶:ControlNet、IP-Adapter 与图像编辑
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址