LoginSignup
3
3

Stable DiffusionのWeb APIを用いて写真的素材をイラストに変換してみた

Posted at

Supershipの名畑です。TVアニメマッシュル-MASHLE-の2期のOPが海外でバズっているという噂は聞いていたけれど、公開一月足らずでYouTubeの動画が2000万再生を超えていてびっくりしました。

はじめに

画像生成モデルであるStable Diffusionではテキストからの画像生成(text-to-image)だけではなく、画像を元にした画像生成(image-to-image)もございます。

今回の記事ではPythonstability.aiのAPIを呼び出すことで「写真を元にしたイラスト生成」を行なっています。

目新しい試みではないというか、私の過去記事「Stable Diffusionでの同じ顔の複数画像生成をPythonとWeb APIで試みた記録」でも過去のモデルで似たことはやっているのですが、あれから半年以上経っているので改めてやってみようと思いました。

余談ですが、現時点において狙った構図の画像を生成するには、やはりなにかしらの元画像を用いるのが手間的な意味で良いのではないかと思っています。今後どうなっていくかはわかりませんが。

注意

  • 元画像、生成画像共に実際の解像度は1024x1024なのですが、記事容量を抑えるために本記事では512x512に変更した上でアップロードしています
  • Web APIは有料です。Web APIを用いずローカルで実行させたい場合はstable-diffusion-webui等をご活用ください

元画像

今回はPhotoshop生成塗りつぶしで用意してみました。

photoshop.png

プロンプトに「Young Japanese woman in a suit drinking coffee at a coffee shop」と入れて生成した画像が以下です。訳すと「喫茶店でコーヒーを飲んでいるスーツ姿の若い日本人女性」です。

init_img.png

コード

今回用いたPythonのコードは下記です。ここではコード内容について詳しくは触れませんので、興味がある方はAPI referenceや過去記事「Stable Diffusionでの画像生成をPythonとWeb APIで実装してみた記録」をご覧ください。

import base64
import os
import requests
import time  # ファイル名にタイムスタンプを入れるために使用

engine_id = "stable-diffusion-xl-1024-v1-0"  # SDXL 1.0

api_host = os.getenv('API_HOST', 'https://api.stability.ai')
api_key = os.getenv("STABILITY_API_KEY")  # 環境変数にAPIキーを保存済み

# API Keyの取得確認
if api_key is None:
    raise Exception("Missing Stability API key.")

# API呼び出し
response = requests.post(
    f"{api_host}/v1/generation/{engine_id}/image-to-image",
    headers={
        "Accept": "application/json",
        "Authorization": f"Bearer {api_key}"
    },
    files={
        "init_image": open("./init_img.png", "rb")
    },
    data={
        "text_prompts[0][text]": "Young Japanese woman in a suit drinking coffee at a coffee shop",
        "text_prompts[0][weight]": 1.0,
        "image_strength": 0.9,  # 元画像の強度
        "style_preset": "anime",  # スタイル
        "seed": 99999  # シード値
    },
)

# レスポンス確認
if response.status_code != 200:
    raise Exception("Non-200 response: " + str(response.text))

# レスポンス取得
data = response.json()

# 画像保存
for i, image in enumerate(data["artifacts"]):
    with open(f"./{engine_id}_{int(time.time())}_{i}.png", "wb") as f:
        f.write(base64.b64decode(image["base64"]))

元画像をそのまま画風だけ変更したいため、プロンプトにはPhotoshopに渡したものと同じ「Young Japanese woman in a suit drinking coffee at a coffee shop」を書きました。

image_strengthが元画像をどれだけ活かすかを示すパラメータ(0〜1)となります。1に近いほど元画像のままで、0に近いほどに元画像から離れていきます。
今回はこの値を0へと徐々に近づけて、どれだけ元画像を保ったまま画風が変わっていくかを記録に残します。

image_strengthを変更しつつ生成した画像たち

image_strength = 0.7

coffee_is_0_7.png

image_strength = 0.5

coffee_is_0_5.png

image_strength = 0.3

coffee_is_0_3.png

image_strength = 0.1

coffee_is_0_1.png

image_strength = 0.01

coffee_is_0_01.png

0.70.5あたりは元画像とそれほど差がないように感じられるかもしれませんが、並べて見るとやっぱり違います。

0.3あたりが最も「元画像の構図を残しつつ画風が変わった」と言える感じでしょうか。
胸のコサージュ的なものが見栄えに悪影響を及ぼしていますが。

プロンプトを変えてみた

画風をさらに変更するため、プロンプトを以下のように変えてました。
moe」を重み0.3として追加しています。

"text_prompts[0][text]": "Young Japanese woman in a suit drinking coffee at a coffee shop",
"text_prompts[0][weight]": 0.7,
"text_prompts[1][text]": "moe",
"text_prompts[1][weight]": 0.3,

0に近づくほどに画風が変わっていることがわかると思います。

image_strength = 0.7

coffee_moe_is_0_7.png

image_strength = 0.5

coffee_moe_is_0_5.png

image_strength = 0.3

coffee_moe_is_0_3.png

image_strength = 0.1

coffee_moe_is_0_01.png

image_strength = 0.01

coffee_moe_is_0_1.png

二つを並べてみた

比較をしやすくするため、結果をすべて並べてみました。変化が明らかです。

strength moe有り moe無し
1.0(元) init_img.png init_img.png
0.7 coffee_moe_is_0_7.png coffee_is_0_7.png
0.5 coffee_moe_is_0_5.png coffee_is_0_5.png
0.3 coffee_moe_is_0_3.png coffee_is_0_3.png
0.1 coffee_moe_is_0_01.png coffee_is_0_1.png
0.01 coffee_moe_is_0_1.png coffee_is_0_01.png

余談 生成塗りつぶし

AIで生成した画像はどうしても部分的におかしな箇所が発生することが多いです。

たとえば今回生成した画像も、左腕に対して左手の位置がおかしいです。

coffee_is_0_3.png

これはコサージュが手として変換されてしまったからですね。

こういった場合の修正方法は色々と考えられますが、今回使ったPhotoshop生成塗りつぶしでさくっとできますので、今更感ありつつご紹介まで。

photoshop2.png

違和感のある部分を選択して、プロンプトとしてなにも入れずに生成を押します。

これだけで以下のように該当箇所だけをAIで再生成した絵が出力できます。

coffee_is_0_3_new.png

さらに同じ要領でちょっといじってみたのが以下です。

coffee_is_0_3_new_2.png

不自然さが0ではないですが、最初よりはかなり良くなったと思います。

余談2 生成拡張

選んだ箇所を拡張する生成拡張という機能もあります。
せっかくなのでこちらもご紹介しておきます。

photoshop3.png

まず、切り抜きツールで拡張する範囲を選択します。

そしてプロンプトを入力せずに生成を押します。

coffee_is_0_3_new_3.png

本当にすごい時代になりました。

最後に

面白かったです。
元画像ありきの画像生成はもっと色々と試していきたい。

宣伝

SupershipのQiita Organizationを合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。

Supershipではプロダクト開発やサービス開発に関わる方を絶賛募集しております。
興味がある方はSupership株式会社 採用サイトよりご確認ください。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3