はじめに
今回の目的は顔写真1枚からその人物の複数の画像を作成することです。環境
Windows 11 CUDA 11.7 Python 3.11
pip install torch==2.0.1+cu117 --index-url https://download.pytorch.org/whl/cu117 pip install diffusers[torch] pip install transformers einops omegaconf pip install git+https://github.com/tencent-ailab/IP-Adapter.git
用意した画像
用意した画像は1枚だけです。結果
リアル画像
アニメ画像
Pythonスクリプト
import torch from diffusers import StableDiffusionPipeline, DDIMScheduler, AutoencoderKL from diffusers.utils import load_image from ip_adapter import IPAdapterFull base_model_path = "pipeline/Realistic_Vision_V4.0_noVAE" image_encoder_path = "IP-Adapter/models/image_encoder/" ip_ckpt = "IP-Adapter/models/ip-adapter-full-face_sd15.safetensors" device = "cuda" noise_scheduler = DDIMScheduler( num_train_timesteps=1000, beta_start=0.00085, beta_end=0.012, beta_schedule="scaled_linear", clip_sample=False, set_alpha_to_one=False, steps_offset=1 ) vae = AutoencoderKL.from_single_file( "vae/realvis4-vae-ft-mse-840000-ema-pruned.safetensors", torch_dtype=torch.float16 ) pipe = StableDiffusionPipeline.from_pretrained( base_model_path, torch_dtype=torch.float16, scheduler=noise_scheduler, vae=vae, feature_extractor=None, safety_checker=None ) ip_model = IPAdapterFull( pipe, image_encoder_path, ip_ckpt, device, num_tokens=257 ) image = load_image("https://cdn-ak.f.st-hatena.com/images/fotolife/t/touch-sp/20231111/20231111140233.png") seed = 20000 scale = 0.7 folder_name = f"seed{seed}_scale{scale}" import os os.makedirs(folder_name, exist_ok=True) images = ip_model.generate( pil_image=image, num_samples=4, prompt="A photo of a girl wearing a black dress, holding red roses in hand, upper body, behind is the Eiffel Tower", width=512, height=704, num_inference_steps=50, scale=scale, seed=seed ) for i in range(4): images[i].save(os.path.join(folder_name, f"result{i}.png"))
補足
背景を白にしたら結果が良くなると書かれているので試してみました。背景削除には「rembg」を使っています。インストールは簡単です。
pip install rembg[gpu,cli]
実行も簡単です。
rembg i -m u2net_human_seg woman.png output.png
その後ARGBをRGBに変更しました。
from PIL import Image import argparse import os parser = argparse.ArgumentParser() parser.add_argument( '--image', type=str, help='path to RGBA image' ) parser.add_argument( '--ext', type=str, default='jpg', help='extension' ) opt = parser.parse_args() img_path = opt.image img_fname = os.path.splitext(os.path.basename(img_path))[0] img = Image.open(img_path) new = Image.new('RGB', img.size, (255, 255, 255)) new.paste(img, mask=img.split()[3]) new.save(f'rgb_{img_fname}.{opt.ext}')
python rgbatorgb.py --image output.png --ext png
結果
左が背景そのまま、右が背景を白に変えた場合です。あまり変わらない印象です。
追記
「FaceID-PlusV2」の記事も書きました。touch-sp.hatenablog.com