Buckets:

mishig's picture
|
download
raw
8.09 kB
# Outpainting
L’outpainting étend une image au-delà de ses limites d’origine, vous permettant d’ajouter, de remplacer ou de modifier des éléments visuels tout en préservant l’image initiale. Tout comme pour l’[inpainting](../using-diffusers/inpaint), l’objectif est de combler la zone blanche (ici, la zone située à l’extérieur de l’image d’origine) avec de nouveaux éléments visuels, tout en conservant l’image d’origine (représentée par un masque de pixels noirs). Il existe plusieurs méthodes pour réaliser un outpainting, par exemple à l’aide d’un [ControlNet](https://hf.co/blog/OzzyGT/outpainting-controlnet) ou de la [Differential Diffusion](https://hf.co/blog/OzzyGT/outpainting-differential-diffusion).
Ce guide vous montre comment effectuer un outpainting avec un modèle d'inpainting, ControlNet et un estimateur ZoeDepth.
Avant de commencer, assurez-vous d'avoir installé la bibliothèque [controlnet_aux](https://github.com/huggingface/controlnet_aux) afin de pouvoir utiliser l'estimateur ZoeDepth.
```py
!pip install -q controlnet_aux
```
## Préparation des images
Commencez par choisir une image à outpainter et supprimez son arrière-plan à l'aide d'un Space comme [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"
>
Par exemple, supprimez l'arrière-plan de cette image d'une paire de chaussures.
image d'origine
fond supprimé
Les modèles [Stable Diffusion XL (SDXL)](../api/pipelines/stable_diffusion/stable_diffusion_xl) fonctionnent de manière optimale avec des images de 1024x1024, mais vous pouvez redimensionner l’image à n’importe quelle taille, à condition que votre matériel dispose de mémoire suffisante pour le supporter. Le fond transparent de l’image doit également être remplacé par un fond blanc. Créez une fonction (comme celle ci-dessous) qui met à l’échelle et colle l’image sur un fond blanc.
```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)
```
Pour éviter d’ajouter des détails superflus, utilisez l’estimateur ZoeDepth pour fournir des indications supplémentaires lors de la génération et vous assurer que les chaussures restent cohérentes avec l’image d’origine.
```py
zoe = ZoeDetector.from_pretrained("lllyasviel/Annotators")
image_zoe = zoe(white_bg_image, detect_resolution=512, image_resolution=1024)
image_zoe
```
## Outpaint
Une fois votre image prête, vous pouvez générer du contenu dans la zone blanche autour des chaussures avec [controlnet-inpaint-dreamer-sdxl](https://hf.co/destitech/controlnet-inpaint-dreamer-sdxl), un ControlNet SDXL entraîné pour l'inpainting.
Chargez le ControlNet d'inpainting, le modèle ZoeDepth et le VAE, puis transmettez-les à [StableDiffusionXLControlNetPipeline](/docs/diffusers/main/fr/api/pipelines/controlnet_sdxl#diffusers.StableDiffusionXLControlNetPipeline). Vous pouvez ensuite créer une fonction optionnelle `generate_image` (pour plus de commodité) afin d'outpaint une image initiale.
```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)
```
Collez l'image d'origine sur l'image initialement outpaintée. Vous améliorerez l'arrière-plan outpainté à une étape ultérieure.
```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]
> C'est le bon moment pour libérer de la mémoire si vous êtes à court !
>
> ```py
> pipeline=None
> torch.cuda.empty_cache()
> ```
Maintenant que vous disposez d'une image outpaintée initiale, chargez le [StableDiffusionXLInpaintPipeline](/docs/diffusers/main/fr/api/pipelines/stable_diffusion/stable_diffusion_xl#diffusers.StableDiffusionXLInpaintPipeline) avec le modèle [RealVisXL](https://hf.co/SG161222/RealVisXL_V4.0) pour générer l'image outpaintée finale avec une meilleure qualité.
```py
pipeline = StableDiffusionXLInpaintPipeline.from_pretrained(
"OzzyGT/RealVisXL_V4.0_inpainting",
dtype=torch.float16,
variant="fp16",
vae=vae,
).to("cuda") # or "mps", "xpu", "cpu"
```
Préparez un masque pour l'image finale après outpainting. Pour créer une transition plus naturelle entre l'image d'origine et l'arrière-plan généré, appliquez un flou au masque afin de faciliter son intégration.
```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
```
Créez un meilleur prompt et transmettez-le à la fonction `generate_outpaint` pour générer l'image finale outpaintée. De nouveau, superposez l'image originale sur le fond outpainté final.
```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:
8.09 kB
·
Xet hash:
2a8dc9da0da16c3899ce4af7c38631163546c9bd72976f49d4a407880ef19be6

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