【SDXL 1.0】ControlNet と Inpaint を組み合わせると何ができるか?

,

はじめに

Diffusers に「StableDiffusionXLControlNetInpaintPipeline」という SDXL 1.0 に対して ControlNet と Inpaint を組み合わせて使えるPipelineが実装されました。

さっそく使ってみたいと思います。

元画像


元画像はぱくたそから使わせて頂きました。
こちらの画像です。

「girl.jpg」として保存しています。

目的

写真に写る人物を別の人物に変えるのが目的です。

ただのInpaintとの違いは、使用するControlNetによって服装や表情などが維持できるところです。

結果



方法

mask画像を作る


人物をマスクするのにOpenMMLabのMMSegmentationを使わせて頂きました。
使い方はこちらを見て下さい。

import numpy as np
from PIL import Image
from mmseg.apis import MMSegInferencer

#checkpoint_name = 'ddrnet_23_in1k-pre_2xb6-120k_cityscapes-1024x1024'
checkpoint_name = 'segformer_mit-b5_8xb2-160k_ade20k-640x640'

inferencer = MMSegInferencer(model=checkpoint_name)

result = inferencer('girl.jpg')['predictions']

mask = np.where(result==12, 255, 0).astype('uint8')
Image.fromarray(mask).save("mask.png")

zoe-depth画像を作る


古いtimmのインストールが必要です。
こちらを見て下さい。

import torch
import numpy as np
from PIL import Image
from diffusers.utils import load_image

torch.hub.help(
    "intel-isl/MiDaS",
    "DPT_BEiT_L_384",
    force_reload=True
    ) 
model_zoe_n = torch.hub.load(
    "isl-org/ZoeDepth",
    "ZoeD_NK",
    pretrained=True
    ).to("cuda")

image = load_image("girl.jpg")

depth_numpy = model_zoe_n.infer_pil(image) 

from zoedepth.utils.misc import colorize
colored = colorize(depth_numpy) 

# gamma correction
img = colored / 255
img = np.power(img, 2.2)
img = (img * 255).astype(np.uint8)

Image.fromarray(img).save("zoe_depth.png")

実行する

いっきに10枚作成しました。

上の4枚はセレクションした結果です。

import torch 
from diffusers.utils import load_image
from diffusers import ControlNetModel, StableDiffusionXLControlNetInpaintPipeline    

controlnet = [
    ControlNetModel.from_pretrained(
        "controlnet/controlnet-zoe-depth-sdxl-1.0",
        torch_dtype=torch.float16
        )
    ]

pipe = StableDiffusionXLControlNetInpaintPipeline.from_pretrained(
    "model/hadukiMix_v10_ema", 
    controlnet=controlnet,
    torch_dtype=torch.float16
    )

pipe.to("cuda")

init_image = load_image("girl.jpg")
zoe_image = load_image("zoe_depth.png")
mask_image = load_image("mask.png")

prompt = "beautiful japanese woman with smile, long hair, 8k, RAW photo, best quality, masterpiece, photo-realistic, focus, professional lighting"
negative_prompt = "worst quality, low quality"
strength=0.95
controlnet_conditioning_scale = 0.45

import os 
os.makedirs("results", exist_ok=True)

for i in range(10):
    seed = 10000 * (i + 1)
    generator = torch.manual_seed(seed)
    image = pipe(
        prompt=prompt,
        negative_prompt=negative_prompt,
        image=init_image,
        mask_image=mask_image,
        control_image=[zoe_image],
        controlnet_conditioning_scale=[controlnet_conditioning_scale],
        strength=strength,
        generator=generator
        ).images[0]

    image.save(os.path.join("results", f"{seed}.png"))

その他

実は以前にもStable Diffusion 1.xの時に同じことをしています。
touch-sp.hatenablog.com
モデルの進化によって格段に画像の質が上がっているのが分かります。

その他の結果はGoogle Bloggerに載せています。
support-touchsp.blogspot.com



このエントリーをはてなブックマークに追加