使用 IP-Adapter 图像修复进行虚拟试穿

虚拟试穿
谈到人工智能和时尚,“虚拟试穿”是最热门、最受欢迎的工具之一。在本博客中,我们将构建自己的虚拟试穿工具。在 🤗 Spaces 中已经有一些非常不错的演示。
OOTDiffusion
OOTDDiffusion 的开源代码已发布在 Github 上。
Outfit Anyone
遗憾的是,他们的 Github 上没有提供扩散模型。此外,似乎只能使用他们的人像,因为我尝试使用自己的图像时报错了。
IP-Adapter
我们将使用 IP-Adapter 构建一个虚拟试穿工具!什么是 *IP-Adapter*?简单来说,*IP-Adapter* 是一种 *图像提示适配器*,可以插入到扩散管道中。
对于虚拟试穿,我们自然会倾向于使用 图像修复。我们对图像中的衣服进行绘制(或遮罩),然后编写一个提示来将衣服更改为其他东西。
这里的问题是,在标准图像修复中,我们只能使用 *文本* 来改变衣服。例如,“粉色连衣裙”。但我想要的不是任何粉色连衣裙,而是 *特定* 粉色连衣裙的照片。这就是 IP-Adapter 的用武之地。我不再使用“粉色连衣裙”这个文本提示,而是给模型提供一张特定粉色连衣裙的图像提示。
我建议阅读 IP-Adapter 论文并查看 GitHub 仓库。此外,🤗 也有其自己的 IP-Adapter 文档,解释得非常清楚。
实现
您可以直接进入 Colab Notebook,或者先阅读博客其余部分,最后再查看 Notebook。*您需要 GPU 才能运行此代码。*
安装库
pip install diffusers accelerate
导入库
from diffusers import AutoPipelineForInpainting, AutoencoderKL
from diffusers.utils import load_image
import torch
加载管道
这个 VAE 减少了运行该模型所需的 RAM 量。
vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", torch_dtype=torch.float16)
让我们将 SDXL 1.0 图像修复模型加载到管道中。
pipeline = AutoPipelineForInpainting.from_pretrained("diffusers/stable-diffusion-xl-1.0-inpainting-0.1",
vae=vae,
torch_dtype=torch.float16,
variant="fp16",
use_safetensors=True
).to("cuda")
我们在这里加载 IP-Adapter。此适配器连接到我们的图像修复管道,并允许我们向管道提供图像提示(或 IP)。
pipeline.load_ip_adapter("h94/IP-Adapter", subfolder="sdxl_models", weight_name="ip-adapter_sdxl.bin", low_cpu_mem_usage=True)
加载图像
首先,我们将加载包含人物的主图像。我使用的是 1024x1024 的 JPG 文件。load_image() 允许您从本地路径或公共 URL 加载图像。这些图像必须是 PIL 图像。建议使用全身图像,模特穿着尽可能少的衣服。*衣服可能会影响最终结果。*
image = load_image('https://cdn-uploads.huggingface.co/production/uploads/648a824a8ca6cf9857d1349c/jpFBKqYB3BtAW26jCGJKL.jpeg').convert("RGB")
接下来,我们将加载我们的服装图像。我强烈建议使用**不**包含人物的服装图像,例如下面的示例。我们在这里不会用到它,但我有一个非常简单的服装分割工具,已发布到 Github 和 Hugging Face。
ip_image = load_image('https://cdn-uploads.huggingface.co/production/uploads/648a824a8ca6cf9857d1349c/NL6mAYJTuylw373ae3g-Z.jpeg').convert("RGB")
最后,我们需要为图像修复管道创建一个遮罩。有很多方法可以做到这一点。我们可以通过简单地绘制遮罩来创建它,或者(*既然我们都是人工智能爱好者*)通过使用图像分割模型!使用图像分割模型的主要好处是它将自动生成遮罩,因此我们所需要做的就是提供人物图像和服装图像,代码将处理其余部分。
我们需要考虑的另一件事是,我们要遮罩人物的哪个部位。躯干?手臂?整条腿?整个身体?要回答这个问题,我们需要知道要扩散到图像中的服装类型。例如,无袖迷你裙只会覆盖部分躯干和部分腿部,而长袖礼服将覆盖整个身体。为了考虑大多数类型的服装,我建议遮罩整个身体。重要的是**不要**遮罩脸部,这样最终图像中的脸部才能看起来像原始图像中的脸部。
为了进行身体分割,让我们使用我的身体分割模块,它可以通过 1 个导入语句和 1 行代码生成身体遮罩。
from SegBody import segment_body
seg_image, mask_image = segment_body(image, face=False)
生成图像
我们需要定义 set_ip_adapter_scale()。此方法控制应用于模型的文本或图像条件化的量。值为 1.0 意味着模型仅受图像提示的条件化。降低此值会鼓励模型生成更多样化的图像,但它们可能与图像提示的对齐程度不高。在虚拟试穿中,我们希望确保最终图像中的服装与 IP 图像相似,因此我们将使用 1.0 的值。
pipeline.set_ip_adapter_scale(1.0)
现在我们已经加载了管道和图像,终于可以生成图像了。我使用这些参数获得了相当不错的结果,但您可以随意调整它们并在此处阅读相关信息。
final_image = pipeline(
prompt="photorealistic, perfect body, beautiful skin, realistic skin, natural skin",
negative_prompt="ugly, bad quality, bad anatomy, deformed body, deformed hands, deformed feet, deformed face, deformed clothing, deformed skin, bad skin, leggings, tights, stockings",
image=image,
mask_image=mask_image,
ip_adapter_image=ip_image,
strength=0.99,
guidance_scale=7.5,
num_inference_steps=100,
).images[0]
还不错!我们成功地用 12 行 Python 代码构建了自己的虚拟试穿工具。是不是很棒?
虚拟试穿功能
让我们将所有内容整合到一个函数中。
def virtual_try_on(img, clothing, prompt, negative_prompt, ip_scale=1.0, strength=0.99, guidance_scale=7.5, steps=100):
_, mask_img = segment_body(img, face=False)
pipeline.set_ip_adapter_scale(ip_scale)
images = pipeline(
prompt=prompt,
negative_prompt=negative_prompt,
image=img,
mask_image=mask_img,
ip_adapter_image=clothing,
strength=strength,
guidance_scale=guidance_scale,
num_inference_steps=steps,
).images
return images[0]
要调用虚拟试穿功能,我们只需执行以下操作:
result = virtual_try_on(img=image,
clothing=ip_image,
prompt="photorealistic, perfect body, beautiful skin, realistic skin, natural skin",
negative_prompt="ugly, bad quality, bad anatomy, deformed body, deformed hands, deformed feet, deformed face, deformed clothing, deformed skin, bad skin, leggings, tights, stockings")
致谢
特别感谢出色的 🤗 Diffusers 团队以及 IP-Adapter 的原作者胡烨、张军、刘思博、韩晓和杨伟。
关于我
大家好,我的名字是 Tony Assi。我是一名驻洛杉矶的设计师。我拥有软件、时尚和营销背景。我目前在一家电子商务时尚品牌工作。查看我的 🤗 个人资料,了解更多应用、模型和数据集。
如有任何问题、意见、业务咨询或工作机会,请随时发送电子邮件至 tony.assi.media@gmail.com。