はじめに
IP-Adapterの進化が止まりません。「FaceID」→「FaceID-Plus」→「FaceID-PlusV2」とどんどん進化しています。今回は今現在最新の「FaceID-PlusV2」を使ってみます。目的
顔写真1枚からその人物の複数の画像を作成することです。PC環境
Windows 11 CUDA 11.8 Python 3.11
Python環境構築
pip install torch==2.0.1+cu118 --index-url https://download.pytorch.org/whl/cu118 pip install diffusers[torch] pip install transformers einops omegaconf pip install git+https://github.com/tencent-ailab/IP-Adapter.git pip install onnxruntime-gpu insightface
結果
用意した画像
用意した画像は1枚だけです。今回作成した画像
以前作成した画像
比較のために「IP-Adapter-Full-Face」を使って以前作成した画像を載せておきます。今回の方が顔の特徴を継承しているように感じます。
こちらの記事で作成しました。
touch-sp.hatenablog.com
今回使用したPythonスクリプト
import cv2 from insightface.app import FaceAnalysis from insightface.utils import face_align import torch from diffusers import StableDiffusionPipeline, DDIMScheduler, AutoencoderKL from PIL import Image from ip_adapter.ip_adapter_faceid import IPAdapterFaceIDPlus app = FaceAnalysis(name="buffalo_l", providers=['CUDAExecutionProvider']) app.prepare(ctx_id=0, det_size=(640, 640)) image = cv2.imread("person.png") faces = app.get(image) faceid_embeds = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0) face_image = face_align.norm_crop(image, landmark=faces[0].kps, image_size=224) v2 = True base_model_path = "model/Realistic_Vision_V4.0_noVAE" vae_model_path = "vae/vae-ft-mse-840000-ema-pruned.safetensors" image_encoder_path = "laion/CLIP-ViT-H-14-laion2B-s32B-b79K" ip_ckpt = "adapter/ip-adapter-faceid-plus_sd15.bin" if not v2 else "adapter/ip-adapter-faceid-plusv2_sd15.bin" 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_model_path).to(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 ) # load ip-adapter ip_model = IPAdapterFaceIDPlus(pipe, image_encoder_path, ip_ckpt, device) # generate image prompt = "A photo of a girl wearing a black dress, holding red roses in hand, upper body, behind is the Eiffel Tower" negative_prompt = "monochrome, lowres, bad anatomy, worst quality, low quality, blurry" images = ip_model.generate( prompt=prompt, negative_prompt=negative_prompt, face_image=face_image, faceid_embeds=faceid_embeds, shortcut=v2, s_scale=1.0, num_samples=4, width=512, height=768, num_inference_steps=30, seed=2023 ) for i in range(4): images[i].save(f"result{i}.png")