はじめに
stable-diffusion-2-depthのpromptをいろいろ変更しながら上記の左側の画像から右側の画像を作成したのでその手順を記録します。手順1
まずは前回と同様にパラメーターを決定しました。touch-sp.hatenablog.com
試行錯誤した結果、以下のように決定しました。
strength: 0.8 guidance_scale: 13.5 num_inference_steps: 50 seed: 238
手順2
手順1で決めたパラメーターを固定したうえでpromptをいろいろいじっていきます。今回、negative promptは固定して実験しています。1(一番最初)
prompt
blonde woman sleeping blue pajamas blue pants
negative prompt
bad deformed ugly duplicate
結果
イラストとしては成立していますが求める金髪女性には程遠いです。
2(「portrait of」を足してみる)
prompt
portrait of blonde woman sleeping blue pajamas blue pants
negative prompt
変更なし結果
目があいてしまったので「portrait of」は不採用にします。
3(「photorealistic」を足してみる)
追加する場所によって全く異なる画像が作成されます。最後にのせているPythonスクリプトを使用して挿入場所を総当たりしています。photorealistic,blonde woman,sleeping,blue pajamas blue pants
blonde woman,photorealistic,sleeping,blue pajamas blue pants
blonde woman,sleeping,photorealistic,blue pajamas blue pants
blonde woman,sleeping,blue pajamas blue pants,photorealistic
4(「octane render」を足してみる)
一気にイラスト風から写真風に変わりました。octane render,blonde woman,sleeping,blue pajamas blue pants,photorealistic
5(「diffused natural skin glow」を足してみる)
肌をきれいにする呪文のようですがなぜかパジャマの首元も整えられました。diffused natural skin glow,octane render,blonde woman,sleeping,blue pajamas blue pants,photorealistic
最終的にいい具合のものができました。
Pythonスクリプト
promptに新しい語句を追加するときに、挿入場所を総当たりするスクリプトを書きました。import os import argparse import datetime import torch from PIL import Image from copy import deepcopy from diffusers import StableDiffusionDepth2ImgPipeline parser = argparse.ArgumentParser() parser.add_argument( '--negative_prompt', action="store_true", help='if enabled, use negative prompt', ) parser.add_argument( '--image', type=str, help='original image' ) parser.add_argument( '--newword', type=str, nargs="*", help='add new words' ) opt = parser.parse_args() original_image = opt.image init_image = Image.open(original_image).convert("RGB").resize((512, 512)) if os.path.isfile('prompt.txt'): print('reading prompts from prompt.txt') with open('prompt.txt', 'r') as f: #prompt = f.read().splitlines() prompt = f.readlines() prompt = [x.strip() for x in prompt if x.strip() != ''] else: prompt = ['anime of tsundere moe kawaii beautiful girl'] if opt.negative_prompt and os.path.isfile('negative_prompt.txt'): print('reading negative prompts from negative_prompt.txt') with open('negative_prompt.txt', 'r') as f: #negative_prompt = f.read().splitlines() negative_prompt = f.readlines() negative_prompt = [x.strip() for x in negative_prompt if x.strip() != ''] negative_prompt = ','.join(negative_prompt) else: negative_prompt = None print(f'negative prompt: {negative_prompt}') model_id = "./stable-diffusion-2-depth" pipe = StableDiffusionDepth2ImgPipeline.from_pretrained(model_id, torch_dtype=torch.float32) pipe.to("cuda") def null_safety(images, **kwargs): return images, False pipe.safety_checker = null_safety os.makedirs('results', exist_ok=True) now = datetime.datetime.today() now_str = now.strftime('%m%d_%H%M') prompt_list = [] if opt.newword: newword_list = opt.newword newword = ' '.join(newword_list) for i in range(len(prompt) + 1): temp = deepcopy(prompt) temp.insert(i, newword) prompt_list.append(temp) else: prompt_list.append(prompt) generator = torch.manual_seed(238) for eachprompt in prompt_list: p = ','.join(eachprompt) print(f'prompt: {p}') image = pipe( prompt = p, negative_prompt = negative_prompt, image = init_image, generator = generator, guidance_scale = 13.5, strength = 0.8, num_inference_steps = 50, num_images_per_prompt = 1).images[0] image.save(os.path.join('results', f'{p}.png'))