已有线稿要用 AI 上色,可以先提取轮廓,再把轮廓作为 ControlNet 的条件,让 Stable Diffusion 按颜色提示生成彩色图。轮廓控制能减少构图漂移,但不会把每块区域锁成指定颜色,也不会保证每条线逐像素保留。
下面用 SD 1.5 与 Canny ControlNet 做入门演示:同一张自绘线稿分别设置 0.5 和 1.0 的控制强度,比较轮廓和着色。代码依据 2026 年 10 月 1 日核对的 Diffusers 0.35.1 与官方模型卡编写,未下载模型运行,示例参数和提示词不代表实测效果。

先准备线稿和 CUDA 环境
适合会运行 Python、想给自有插画尝试颜色方案的读者。准备 512×512 的 RGB 线稿 line.png:白底、黑线、主体轮廓清楚,去掉扫描阴影和无关文字。若原图比例不同,先在编辑器裁切或补边,避免为了这个尺寸拉伸人物。这个流程会生成新的彩色解释稿;要求出版线条绝对不动时,应把结果作为配色参考,再用绘图软件填色或分层合成。
在自己的 Python 环境中按 PyTorch 安装页配置相应 CUDA 版,再安装以下依赖。可用性检查为 False 时先修环境,不能直接运行后面的 float16 GPU 示例。
python -c "import torch; print(torch.__version__, torch.cuda.is_available())"
python -m pip install diffusers==0.35.1 transformers==4.56.2 accelerate==1.10.1 safetensors pillow opencv-python numpy
把线稿转成 ControlNet 需要的轮廓图
Canny 模型卡说明它使用黑底白边的轮廓图,并基于 SD 1.5 训练。本文使用 StableDiffusionControlNetPipeline,接口所属管线见 Diffusers ControlNet 文档。不要把 SD 1.5 适配器直接接到 SDXL 底模上。
保存下面完整代码为 color_line.py。先检查输出的 edges.png:主要轮廓应可见,没有被大面积噪点替代。Canny 的 100 和 200 是边缘检测阈值,不是生成控制权重;细线漏检时先调整这两个阈值再做生成。
from pathlib import Path
import cv2
import numpy as np
import torch
from PIL import Image
from diffusers import ControlNetModel, StableDiffusionControlNetPipeline
source = Image.open("line.png").convert("RGB")
if source.size != (512, 512):
raise ValueError("请先把线稿裁切或补边至512×512")
gray = cv2.cvtColor(np.array(source), cv2.COLOR_RGB2GRAY)
edge = cv2.Canny(gray, 100, 200)
if not np.any(edge):
raise ValueError("轮廓为空,请先检查线稿及阈值")
control_image = Image.fromarray(np.repeat(edge[:, :, None], 3, axis=2))
control_image.save("edges.png")
controlnet = ControlNetModel.from_pretrained(
"lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16,
)
pipe = StableDiffusionControlNetPipeline.from_pretrained(
"stable-diffusion-v1-5/stable-diffusion-v1-5",
controlnet=controlnet, torch_dtype=torch.float16,
variant="fp16", use_safetensors=True,
)
pipe.enable_model_cpu_offload()
out = Path("colored")
out.mkdir(exist_ok=True)
prompt = "a girl with short brown hair, red coat, blue scarf, clean colored illustration, white background"
for scale in (0.5, 1.0):
image = pipe(
prompt=prompt, image=control_image,
controlnet_conditioning_scale=scale,
num_inference_steps=30, guidance_scale=7.5,
generator=torch.Generator(device="cpu").manual_seed(42),
height=512, width=512,
).images[0]
image.save(out / f"control_{scale:.1f}.png")
如果你的线稿不是女孩,就改 prompt 中的主体和颜色,不要保留这个虚构描述。第一次会下载底模和控制模型;CPU offload 能减轻显存占用,但不保证任意 GPU 都能运行。
比较 0.5 与 1.0,不同时修改其他参数
运行 python color_line.py 后,应出现 edges.png,以及 colored/control_0.5.png、colored/control_1.0.png。官方使用指南用 controlnet_conditioning_scale 调整条件影响。把两张生成图与原线稿叠放,降低上层透明度,核对头部位置、脸部外轮廓、衣服边界和主要道具是否移动。
| 检查项目 | 具体看什么 | 下一步 |
|---|---|---|
| 轮廓 | 肩线、外套边和手部位置是否偏离 | 漂移明显先提高控制强度,仍有问题回查 edges.png |
| 颜色 | 红色是否落在外套,蓝色是否落在围巾 | 颜色串区时简化描述;必要时改用分区蒙版或人工填色 |
| 线条 | 细线是否重复成双边,局部是否多出纹理 | 清理输入噪点、调整边缘阈值,避免把阴影也当轮廓 |
代码每次都重新创建相同种子的 Generator,避免第一张图消耗随机状态后影响第二张的比较。保持提示词、模型、尺寸、步数与引导强度不变,一次只改控制强度。两个数是对照起点,不是统一质量标准。
哪些情况应该换做法
品牌色、漫画分层或严谨动画设定需要区域颜色稳定,Canny 只提供轮廓条件,不能保证红衣服每次都准确。先用它探索配色,再在原线稿层下人工修颜色,比把生成稿当成最终分色文件可靠。
底模的许可与限制见 SD 1.5 模型卡;控制模型也有独立许可。下载公开模型不代表任何输入和用途都得到授权。对于手指、脸和小字,生成后仍要逐项检查。
为什么输入黑线,ControlNet 用白线?
原画给人看,Canny 图给控制模型看。边缘检测输出黑底白边,所以代码并没有直接把整张白底线稿当作条件图。先确认 edges.png,再看生成结果,可以区分“没提取到轮廓”和“模型没有充分遵循轮廓”。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31942.html