Diffusers 文件

外擴繪製

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

影像外繪

影像外繪將影像擴充套件到其原始邊界之外,允許您在保留原始影像的同時新增、替換或修改影像中的視覺元素。與影像修復類似,您需要用新的視覺元素填充白色區域(在這種情況下,是原始影像之外的區域),同時保留原始影像(由黑色畫素蒙版表示)。有幾種影像外繪的方法,例如使用ControlNet差異擴散

本指南將向您展示如何使用影像修復模型、ControlNet 和 ZoeDepth 估計器進行影像外繪。

在開始之前,請確保您已安裝 controlnet_aux 庫,以便您可以使用 ZoeDepth 估計器。

!pip install -q controlnet_aux

影像準備

首先選擇一張要進行影像外繪的影像,並使用 BRIA-RMBG-1.4 等空間移除背景。

例如,移除這雙鞋影像的背景。

原始影像
背景已移除

Stable Diffusion XL (SDXL) 模型最適合 1024x1024 影像,但您可以將影像調整為任何大小,只要您的硬體有足夠的記憶體來支援它。影像中的透明背景也應該替換為白色背景。建立一個函式(如下所示),將影像縮放並貼上到白色背景上。

import random

import requests
import torch
from controlnet_aux import ZoeDetector
from PIL import Image, ImageOps

from diffusers import (
    AutoencoderKL,
    ControlNetModel,
    StableDiffusionXLControlNetPipeline,
    StableDiffusionXLInpaintPipeline,
)

def scale_and_paste(original_image):
    aspect_ratio = original_image.width / original_image.height

    if original_image.width > original_image.height:
        new_width = 1024
        new_height = round(new_width / aspect_ratio)
    else:
        new_height = 1024
        new_width = round(new_height * aspect_ratio)

    resized_original = original_image.resize((new_width, new_height), Image.LANCZOS)
    white_background = Image.new("RGBA", (1024, 1024), "white")
    x = (1024 - new_width) // 2
    y = (1024 - new_height) // 2
    white_background.paste(resized_original, (x, y), resized_original)

    return resized_original, white_background

original_image = Image.open(
    requests.get(
        "https://huggingface.co/datasets/stevhliu/testing-images/resolve/main/no-background-jordan.png",
        stream=True,
    ).raw
).convert("RGBA")
resized_img, white_bg_image = scale_and_paste(original_image)

為了避免新增不需要的額外細節,請使用 ZoeDepth 估計器在生成過程中提供額外指導,並確保鞋子與原始影像保持一致。

zoe = ZoeDetector.from_pretrained("lllyasviel/Annotators")
image_zoe = zoe(white_bg_image, detect_resolution=512, image_resolution=1024)
image_zoe

影像外繪

影像準備就緒後,您可以使用 controlnet-inpaint-dreamer-sdxl(一個為影像修復而訓練的 SDXL ControlNet)在鞋子周圍的白色區域生成內容。

載入影像修復 ControlNet、ZoeDepth 模型、VAE,並將它們傳遞給 StableDiffusionXLControlNetPipeline。然後,您可以建立一個可選的 generate_image 函式(為了方便),以對初始影像進行影像外繪。

controlnets = [
    ControlNetModel.from_pretrained(
        "destitech/controlnet-inpaint-dreamer-sdxl", torch_dtype=torch.float16, variant="fp16"
    ),
    ControlNetModel.from_pretrained(
        "diffusers/controlnet-zoe-depth-sdxl-1.0", torch_dtype=torch.float16
    ),
]
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16).to("cuda")
pipeline = StableDiffusionXLControlNetPipeline.from_pretrained(
    "SG161222/RealVisXL_V4.0", torch_dtype=torch.float16, variant="fp16", controlnet=controlnets, vae=vae
).to("cuda")

def generate_image(prompt, negative_prompt, inpaint_image, zoe_image, seed: int = None):
    if seed is None:
        seed = random.randint(0, 2**32 - 1)

    generator = torch.Generator(device="cpu").manual_seed(seed)

    image = pipeline(
        prompt,
        negative_prompt=negative_prompt,
        image=[inpaint_image, zoe_image],
        guidance_scale=6.5,
        num_inference_steps=25,
        generator=generator,
        controlnet_conditioning_scale=[0.5, 0.8],
        control_guidance_end=[0.9, 0.6],
    ).images[0]

    return image

prompt = "nike air jordans on a basketball court"
negative_prompt = ""

temp_image = generate_image(prompt, negative_prompt, white_bg_image, image_zoe, 908097)

將原始影像貼上到初始外繪影像上。您將在後續步驟中改進外繪背景。

x = (1024 - resized_img.width) // 2
y = (1024 - resized_img.height) // 2
temp_image.paste(resized_img, (x, y), resized_img)
temp_image

如果記憶體不足,現在是釋放一些記憶體的好時機!

pipeline=None
torch.cuda.empty_cache()

現在您已經有了初始外繪影像,載入帶有 RealVisXL 模型的 StableDiffusionXLInpaintPipeline 以生成更高質量的最終外繪影像。

pipeline = StableDiffusionXLInpaintPipeline.from_pretrained(
    "OzzyGT/RealVisXL_V4.0_inpainting",
    torch_dtype=torch.float16,
    variant="fp16",
    vae=vae,
).to("cuda")

為最終外繪影像準備一個蒙版。為了在原始影像和外繪背景之間建立更自然的過渡,模糊蒙版以幫助其更好地融合。

mask = Image.new("L", temp_image.size)
mask.paste(resized_img.split()[3], (x, y))
mask = ImageOps.invert(mask)
final_mask = mask.point(lambda p: p > 128 and 255)
mask_blurred = pipeline.mask_processor.blur(final_mask, blur_factor=20)
mask_blurred

建立更好的提示並將其傳遞給 generate_outpaint 函式以生成最終的外繪影像。再次,將原始影像貼上到最終的外繪背景上。

def generate_outpaint(prompt, negative_prompt, image, mask, seed: int = None):
    if seed is None:
        seed = random.randint(0, 2**32 - 1)

    generator = torch.Generator(device="cpu").manual_seed(seed)

    image = pipeline(
        prompt,
        negative_prompt=negative_prompt,
        image=image,
        mask_image=mask,
        guidance_scale=10.0,
        strength=0.8,
        num_inference_steps=30,
        generator=generator,
    ).images[0]

    return image

prompt = "high quality photo of nike air jordans on a basketball court, highly detailed"
negative_prompt = ""

final_image = generate_outpaint(prompt, negative_prompt, temp_image, mask_blurred, 7688778)
x = (1024 - resized_img.width) // 2
y = (1024 - resized_img.height) // 2
final_image.paste(resized_img, (x, y), resized_img)
final_image
< > 在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.