Buckets:

mishig's picture
|
download
raw
9.76 kB
# Outpainting
Outpainting расширяет изображение за пределы его исходных границ, позволяя добавлять, заменять или изменять визуальные элементы, сохраняя при этом исходное изображение. Как и в случае с [inpainting](../using-diffusers/inpaint), вам нужно заполнить белую область (в данном случае — область за пределами исходного изображения) новыми визуальными элементами, сохранив исходное изображение (представленное маской из чёрных пикселей). Существует несколько способов outpainting, например, с помощью [ControlNet](https://hf.co/blog/OzzyGT/outpainting-controlnet) или [Differential Diffusion](https://hf.co/blog/OzzyGT/outpainting-differential-diffusion).
В этом руководстве показано, как выполнять outpainting с помощью модели inpainting, ControlNet и оценщика глубины ZoeDepth.
Перед началом убедитесь, что библиотека [controlnet_aux](https://github.com/huggingface/controlnet_aux) установлена, чтобы вы могли использовать оценщик ZoeDepth.
```py
!pip install -q controlnet_aux
```
## Подготовка изображений
Начните с выбора изображения для outpainting и удалите фон с помощью Space, например [BRIA-RMBG-1.4](https://hf.co/spaces/briaai/BRIA-RMBG-1.4).
<iframe src="https://briaai-bria-rmbg-1-4.hf.space" frameborder="0" width="850" height="450"
>
Например, удалите фон с этого изображения пары обуви.
original image
фон удален
Модели [Stable Diffusion XL (SDXL)](../api/pipelines/stable_diffusion/stable_diffusion_xl) лучше всего работают с изображениями размером 1024x1024, но вы можете изменить размер изображения до любого значения, если вашей аппаратной части достаточно памяти для этого. Прозрачный фон на изображении также следует заменить на белый. Создайте функцию (например, такую, как приведена ниже), которая масштабирует изображение и наклеивает его на белый фон.
```py
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 для предоставления дополнительных ориентиров при генерации и обеспечения согласованности обуви с исходным изображением.
```py
zoe = ZoeDetector.from_pretrained("lllyasviel/Annotators")
image_zoe = zoe(white_bg_image, detect_resolution=512, image_resolution=1024)
image_zoe
```
## Outpaint
Когда ваш образ будет готов, вы можете сгенерировать контент в белой области вокруг обуви с помощью [controlnet-inpaint-dreamer-sdxl](https://hf.co/destitech/controlnet-inpaint-dreamer-sdxl), SDXL ControlNet, обученного для inpainting.
Загрузите ControlNet для inpainting, модель ZoeDepth и VAE и передайте их в [StableDiffusionXLControlNetPipeline](/docs/diffusers/main/ru/api/pipelines/controlnet_sdxl#diffusers.StableDiffusionXLControlNetPipeline). Затем вы можете создать необязательную функцию `generate_image` (для удобства), чтобы выполнить outpainting исходного изображения.
```py
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)
```
Наложите исходное изображение на первоначальное изображение с расширенным фоном. Вы улучшите расширенный фон на следующем шаге.
```py
x = (1024 - resized_img.width) // 2
y = (1024 - resized_img.height) // 2
temp_image.paste(resized_img, (x, y), resized_img)
temp_image
```
> [!TIP]
> Сейчас самое время освободить память, если её осталось мало!
>
> ```py
> pipeline=None
> torch.cuda.empty_cache()
> ```
Теперь, когда у вас есть начальное изображение с расширенной областью, загрузите [StableDiffusionXLInpaintPipeline](/docs/diffusers/main/ru/api/pipelines/stable_diffusion/stable_diffusion_xl#diffusers.StableDiffusionXLInpaintPipeline) с моделью [RealVisXL](https://hf.co/SG161222/RealVisXL_V4.0), чтобы сгенерировать финальное изображение с расширенной областью более высокого качества.
```py
pipeline = StableDiffusionXLInpaintPipeline.from_pretrained(
"OzzyGT/RealVisXL_V4.0_inpainting",
dtype=torch.float16,
variant="fp16",
vae=vae,
).to("cuda") # or "mps", "xpu", "cpu"
```
Подготовьте маску для итогового изображения после аутпейнта. Чтобы создать более естественный переход между исходным изображением и аутпейнт-фоном, размойте маску, чтобы она лучше сливалась с изображением.
```py
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`, чтобы сгенерировать итоговое изображение с расширенным фоном. Снова наложите исходное изображение на итоговый фон.
```py
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
```

Xet Storage Details

Size:
9.76 kB
·
Xet hash:
5e4cc9f7011eed27cb33be0fcd3ddb474f1ef3f15651fb16c30ace0416098f7b

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.