Diffusers documentation
Outpainting
Outpainting
Outpainting, bir görüntüyü orijinal sınırlarının ötesine uzatarak, orijinal görüntüyü korurken görsel öğeleri eklemenize, değiştirmenize veya düzenlemenize olanak tanır. Inpainting'de olduğu gibi, orijinal görüntüyü (siyah piksellerden oluşan bir maske ile temsil edilir) koruyarak beyaz alanı (bu durumda, orijinal görüntünün dışındaki alan) yeni görsel öğelerle doldurmak istersiniz. Outpainting için ControlNet veya Differential Diffusion gibi birkaç yöntem bulunmaktadır.
Bu kılavuz, bir inpainting modeli, ControlNet ve ZoeDepth tahminleyicisi kullanarak outpainting yapmayı size gösterecektir.
Başlamadan önce, ZoeDepth tahmincisini kullanabilmek için controlnet_aux kütüphanesinin yüklü olduğundan emin olun.
!pip install -q controlnet_aux
Görsel hazırlama
Önce BRIA-RMBG-1.4 gibi bir Space ile arka planı kaldırarak outpaint yapılacak bir görsel seçerek başlayın.
Örneğin, bu ayakkabı çiftinin görselinden arka planı kaldırın.
Stable Diffusion XL (SDXL) modelleri 1024x1024 boyutundaki görsellerle en iyi sonucu verir, ancak donanımınızın bunu destekleyecek kadar belleğe sahip olması koşuluyla görseli herhangi bir boyuta yeniden boyutlandırabilirsiniz. Görseldeki şeffaf arka planın da beyaz bir arka planla değiştirilmesi gerekir. Görseli ölçekleyip beyaz bir arka plana yapıştıran bir fonksiyon (aşağıdaki gibi) oluşturun.
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)İstenmeyen ek detayların eklenmesini önlemek için, ayakkabıların orijinal görüntüyle tutarlı kalmasını sağlamak ve üretim sırasında ek yönlendirme sunmak üzere ZoeDepth tahmincisini kullanın.
zoe = ZoeDetector.from_pretrained("lllyasviel/Annotators")
image_zoe = zoe(white_bg_image, detect_resolution=512, image_resolution=1024)
image_zoe
Outpaint
Görsel hazır olduğunda, inpainting için eğitilmiş bir SDXL ControlNet olan controlnet-inpaint-dreamer-sdxl ile ayakkabıların etrafındaki beyaz alanda içerik üretebilirsiniz.
Inpainting ControlNet, ZoeDepth modelini ve VAE'yi yükleyip bunları StableDiffusionXLControlNetPipeline nesnesine iletin. Ardından, başlangıç görselini outpaint etmek için isteğe bağlı bir generate_image fonksiyonu (kolaylık sağlamak amacıyla) oluşturabilirsiniz.
controlnets = [
ControlNetModel.from_pretrained(
"destitech/controlnet-inpaint-dreamer-sdxl", dtype=torch.float16, variant="fp16"
),
ControlNetModel.from_pretrained(
"diffusers/controlnet-zoe-depth-sdxl-1.0", dtype=torch.float16
),
]
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", dtype=torch.float16).to("cuda") # or "mps", "xpu", "cpu"
pipeline = StableDiffusionXLControlNetPipeline.from_pretrained(
"SG161222/RealVisXL_V4.0", 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)Orijinal görüntüyü başlangıçta oluşturulan genişletilmiş görüntünün üzerine yapıştırın. Genişletilen arka planı sonraki bir adımda iyileştireceksiniz.
x = (1024 - resized_img.width) // 2
y = (1024 - resized_img.height) // 2
temp_image.paste(resized_img, (x, y), resized_img)
temp_image
Bellek azalıyorsa, biraz bellek boşaltmak için şimdi iyi bir zaman!
pipeline=None torch.cuda.empty_cache()
Şimdi elinizde başlangıç düzeyinde bir outpainting görseli var; daha iyi kalitede nihai outpainting görselini üretmek için StableDiffusionXLInpaintPipeline'ı RealVisXL modeliyle yükleyin.
pipeline = StableDiffusionXLInpaintPipeline.from_pretrained(
"OzzyGT/RealVisXL_V4.0_inpainting",
dtype=torch.float16,
variant="fp16",
vae=vae,
).to("cuda") # or "mps", "xpu", "cpu"Son outpainting görüntüsü için bir maske hazırlayın. Orijinal görüntü ile outpainting arka planı arasında daha doğal bir geçiş oluşturmak için maskenin daha iyi birleşmesine yardımcı olmak üzere maskeyi bulanıklaştırın.
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
Daha iyi bir prompt oluşturun ve son outpainting görselini üretmek için generate_outpaint fonksiyonuna iletin. Tekrar, orijinal görseli son outpainting arka planının üzerine yapıştırın.
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