【Diffusers】【Inpaint】StableDiffusionInpaintPipeline と MaskedStableDiffusionImg2ImgPipeline の違いを比較してみました。

はじめに

Inpaintは画像の一部修正をすることです。

Inpaint専用モデルもありますが、今回は通常のText2Imageモデルを使用してInpaintを行います。

「yabalMixTrue25D_v5」というモデルを使用しました。

使い方が2通りあるので、両方を実行して比較してみました。

用意した画像

こちらの画像を使用しました。

この画像の作り方はこちらを見てください。

今回やること

スカートをデニムに変えてみます。

用意したマスク画像

画像のどの部分を変更するかを指定するための画像です。

こちらの画像を用意しました。

女性の下半身の部分を白く塗りつぶした画像です。

こちらのスクリプトで作成しました。

結果

「StableDiffusionInpaintPipeline」を使う方法と「MaskedStableDiffusionImg2ImgPipeline」を使う方法の2通りで実行しました。

StableDiffusionInpaintPipeline

左から「strength」を0.7 → 0.75 → 0.8 → 0.85と変化させています。
マスクされていない部分を変更しないようにVaeImageProcessor.apply_overlay methodというのを使用しています。

「strength」の値が小さいと元の白いスカートが残ってしまっています。

MaskedStableDiffusionImg2ImgPipeline

左から「strength」を0.7 → 0.75 → 0.8 → 0.85と変化させています。

ネガティブプロンプトに「bag」と書いておきましたがカバンが描写されてしまいました。

ベストショット

「StableDiffusionInpaintPipeline」を使って、「strength」を0.8に設定した時の結果を今回のベストショットとしました。

使用したPythonスクリプト

StableDiffusionInpaintPipeline

from diffusers import AutoPipelineForInpainting, EulerAncestralDiscreteScheduler
import torch
from diffusers.utils import load_image

pipeline = AutoPipelineForInpainting.from_pretrained(
    "model/yabalMixTrue25D_v5",
    safety_checker=None
)
pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
pipeline.to("cuda")

init_image = load_image("girl.png").resize((512, 768))
mask_image = load_image("girl_mask.png").resize((512, 768))
blurred_mask = pipeline.image_processor.blur(mask_image, blur_factor=8)

strength_list = [0.7, 0.75, 0.8, 0.85]

for strength in strength_list:
    generator = torch.manual_seed(2024)
    images = pipeline(
        prompt="masterpiece, absurdres, best quality, blue denim, full body, outdoors, day, countryside, hand on hip", 
        image = init_image,
        mask_image = blurred_mask,
        negative_prompt="bag, porch, monochrome, lowres, bad anatomy, worst quality, low quality", 
        num_images_per_prompt=1, 
        num_inference_steps=50,
        generator=generator,
        strength=strength,
        cfg_scale=9.0,
        width=512,
        height=768
    ).images

    unmasked_unchanged_image = pipeline.image_processor.apply_overlay(
        blurred_mask,
        init_image,
        images[0]
    )
    unmasked_unchanged_image.save(f"inpaint_normal_{strength}.png")

MaskedStableDiffusionImg2ImgPipeline

from diffusers import DiffusionPipeline, EulerAncestralDiscreteScheduler
import torch
from diffusers.utils import load_image

pipeline = DiffusionPipeline.from_pretrained(
    "model/yabalMixTrue25D_v5",
    safety_checker=None,
    custom_pipeline="masked_stable_diffusion_img2img"
)
pipeline.scheduler = EulerAncestralDiscreteScheduler.from_config(pipeline.scheduler.config)
pipeline.to("cuda")

init_image = load_image("girl.png").resize((512, 768))
mask_image = load_image("girl_mask.png").resize((512, 768))
blurred_mask = pipeline.image_processor.blur(mask_image, blur_factor=8)

strength_list = [0.7, 0.75, 0.8, 0.85]

for strength in strength_list:
    generator = torch.manual_seed(2024)
    images = pipeline(
        prompt="masterpiece, absurdres, best quality, blue denim, full body, outdoors, day, countryside, hand on hip", 
        image = init_image,
        mask = blurred_mask,
        negative_prompt="bag, porch, monochrome, lowres, bad anatomy, worst quality, low quality", 
        num_images_per_prompt=1, 
        num_inference_steps=50,
        strength=strength,
        generator=generator
    ).images

    unmasked_unchanged_image = pipeline.image_processor.apply_overlay(
        blurred_mask,
        init_image,
        images[0]
    )
    unmasked_unchanged_image.save(f"inpaint_masked_{strength}.png")





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