ジャコ Lab

プログラミング関連のメモ帳的ブログです

ControlNet の Lineart を使ってみる

huggingface.co

ControlNet の Lineart を使ってみます。
Line Art、線画ですね!これは調べなくてもわかります!

Lineart

Canny や MLSD に似た、線を抽出して ControlNet で使う系のものでしょう。

controlnet_aux が必要です

!pip install -U controlnet_aux

投入画像の準備

from diffusers.utils import load_image
from controlnet_aux import LineartDetector

init_image_url = "https://huggingface.co/ControlNet-1-1-preview/control_v11p_sd15_lineart/resolve/main/images/input.png"
init_image = load_image(init_image_url)
init_image = init_image.resize((512, 512))

processor = LineartDetector.from_pretrained("lllyasviel/Annotators")
control_image = processor(init_image)

(左) 投入画像 | (右) LineArt 検出した画像

アスペクト比...

ControlNet, Pipeline の準備

import torch
from diffusers import ControlNetModel, StableDiffusionControlNetPipeline, UniPCMultistepScheduler

# ControlNet の準備
controlnet = ControlNetModel.from_pretrained(
    "ControlNet-1-1-preview/control_v11p_sd15_lineart", 
    torch_dtype=torch.float16
)

# Pipeline の準備
pipe = StableDiffusionControlNetPipeline.from_pretrained(
    "runwayml/stable-diffusion-v1-5",
    torch_dtype=torch.float16,
    controlnet=controlnet
).to("cuda")
pipe.enable_model_cpu_offload()

# スケジューラーの設定
pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)

ControlNet の Model 名だけ異なるいつものやつ

ControlNet のモデル名がリポジトリと異なりますね?lllyasviel/control_v11p_sd15_lineartを使用したほうが良いとかあるのかしら?

Duplicate from ControlNet-1-1-preview/control_v11p_sd15_lineart

とコメント付いているし、全く同じものっぽいですね。

パイプライン実行

prompt = "michael jackson concert"
image = pipe(
    prompt, 
    num_inference_steps=30, 
    generator=torch.manual_seed(0), 
    image=control_image
).images[0]
image

アスペクト比は維持してみよう

元画像のサイズを調べる

init_image_url = "https://huggingface.co/ControlNet-1-1-preview/control_v11p_sd15_lineart/resolve/main/images/input.png"
init_image = load_image(init_image_url)
init_image.size

# => (1600, 2400)

2:3 でした。

リサイズ値を調整してみる

init_image_url = "https://huggingface.co/ControlNet-1-1-preview/control_v11p_sd15_lineart/resolve/main/images/input.png"
init_image = load_image(init_image_url)
(w, h) = init_image.size
scale = h / w
init_image = init_image.resize((512, int(512 * scale)))

processor = LineartDetector.from_pretrained("lllyasviel/Annotators")
control_image = processor(init_image)
resize() は float はダメみたいなので int で丸めておきます

いざ!

Seed: 0 だと、512x512 の方が良かったかもしれない!

まとめ

線画から画像を生成するので、Stable Diffusion が塗り絵をしてくれる感じですね!