スペリング能力が向上したStable Diffusion 3で文字を含む画像を生成してみた(DALL·E 3との比較もしてみた)

[Supership](https://supership.jp/)の名畑です。[響け！ユーフォニアム3](https://anime-eupho.com/)を見ながら、本当に、アニメーション作品としての質が高いなと感じるわけです。アニメーションとは命を吹き込むことだなと。

## はじめに

[Stability AI](https://ja.stability.ai/)が今年の2月、画像生成モデルである[Stable Diffusion 3.0](https://stability.ai/news/stable-diffusion-3)を発表し、話題となりました。

> Stable Diffusion 3は旧モデルと比較して、画質および様々なプロンプトへの対応が大幅に向上した最新のText 2 Imageモデルだ。
>
> 特にこれまでのモデルでは難しかった「画像内での正確なアルファベット表記」が可能になっている。
> 
> 参考：[ASCII.jp：テキストが崩れない！ 画像生成AIの最新版「Stable Diffusion 3」登場](https://ascii.jp/elem/000/004/186/4186013/)

この**Stable Diffusion 3.0**が先日、APIで利用可能になりました。

> Stability AIは4月17日、2月22日にプレビュー版を発表した最新の画像生成AIモデル「Stable Diffusion 3」、その高速版である「Stable Diffusion 3 Turbo」、そしてこれらを搭載したAIチャットボット「Stable Assistant」を発表した。
>
> 参考：[ASCII.jp：画像生成AI「Stable Diffusion 3」API利用可能に　文字の正確さが強み](view-source:https://ascii.jp/elem/000/004/194/4194727/)

ということで今回の記事ではこの**Stable Diffusion 3.0**を使ってみます。

スペリング能力が向上したとのことなので、文字を埋め込んだ画像を生成してみました。

## 注意

- 生成画像の解像度は**1024x1024**なのですが、記事容量を抑えるため、本記事では**512x512**に変換した上でアップロードしています
- 本APIは[有料](https://platform.stability.ai/pricing)です。現時点では1画像生成につき**SD3**(Stable Diffusion 3.0)は6クレジット、**SD3 Turbo**では4.5クレジットとなります。1,000クレジットにつき10ドルのため、仮に1ドル150円とすると、**1画像につき9円と6.75円**です。

## API Key

[Developer Platform](https://platform.stability.ai/)でAPI Keyを発行する必要があります。

ハードコーディングを避けるため、環境変数にでも保存しておきましょう。今回は**STABILITY\_API\_KEY**という名称で保存されていると仮定して進めます。

```
export STABILITY_API_KEY =ここに取得したAPI keyを書く
```


## コード

画像生成に用いたPythonのコードは以下です。

```Python
import os
import requests
import time

api_host = "https://api.stability.ai/v2beta/stable-image/generate/sd3"
prompt = "ここにプロンプトを書く"
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(
    api_host,
    headers={
        "Authorization": f"Bearer {api_key}",
        "accept": "image/*"
    },
    files={
        "none": ""
    },
    data={
        "prompt": prompt,
        "output_format": "png"
    },
)

# 画像保存
# ファイル名にはタイムスタンプとプロンプトを含めている
if response.status_code == 200:
    with open(f"./{int(time.time())}_{prompt}.png", "wb") as file:
        file.write(response.content)
else:
    raise Exception(str(response.json()))
```

本コードは最低限のものとなっています。
アスペクト比の変更やシード値の指定などについては[API Reference](https://platform.stability.ai/docs/api-reference#tag/Generate/paths/~1v2beta~1stable-image~1generate~1sd3/post)をご覧ください。

## An old man wearing a T-shirt that says 'Otaku'

まずはシンプルな言葉で試してみます。

```python
prompt = "An old man wearing a T-shirt that says 'Otaku'"
```

日本語にすると「**'Otaku'と書かれたTシャツを着た老夫**」ですね。

結果は以下です。

![sd3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/6d444aa4-7ade-4cda-964f-6688e2719c12.png)

大文字と小文字の違いはありますが、それ以外は意図通りです。
文字が少しTシャツから浮いてしまっている感はありますが。

素晴らしい結果です。

## A young Japanese woman holding a piece of paper that says 'Touken Ranbu'

次は固有名詞にしてみます。

```python
prompt = "A young Japanese woman holding a piece of paper that says 'Touken Ranbu'"
```

日本語にすると「**'Touken Ranbu'と書かれた紙を持っている若い日本人女性**」になります。**Touken Ranbu**はもちろん[刀剣乱舞](https://www.toukenranbu.jp/)のことです。[アニメ『刀剣乱舞 廻』](https://touken-kai.jp/)は絶賛放送中です。

結果は以下です。

![sd3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/1dd16633-4604-affb-ee90-51701fefe706.png)

これも意図通りです。
狙った結果で嬉しいです。

指が生成AIでよくありがちな感じになってしまっていますが、今回はスルーします。

## A sign that says 'In the name of the moon, I shall punish you!'

次は文章で挑戦してみようと思います。
日本人ならほぼ誰もが知っているであろう名言の英訳です。

```python
prompt = "A sign that says 'In the name of the moon, I shall punish you!'"
```

日本語に訳すと「**'In the name of the moon, I shall punish you!'と書かれた看板**」ですね。

「**In the name of the moon, I shall punish you!**」は「**月に代わっておしおきよ!**」の英訳です。[美少女戦士セーラームーン](https://sailormoon-official.com/)です。

参考：[月に代わっておしおきよ！って英語でなんて言うの？ - DMM英会話なんてuKnow?](https://eikaiwa.dmm.com/uknow/questions/2157/)

結果は以下です。

![sd3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/c6ca74b1-3c79-e77e-89ec-c449a79f0cc9.png)

一部ミスがあるのが惜しいです。
しかし、かなりプロンプトに近い感じにはなっています。

## A screen projected with 'Bling-Bang-Bang-Born'

もう少し短い英語で試してみます。

```python
prompt = "A screen projected with 'Bling-Bang-Bang-Born'"
```

日本語に訳すと「**'Bling-Bang-Bang-Born'と投影されたスクリーン**」となります。[Bling-Bang-Bang-Born](https://www.youtube.com/watch?v=mLW35YMzELE)は流行りまくったのでもう説明は不要でしょう。

結果は以下です。

![sd3_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/0c77f26e-033b-fc20-3032-021cc5e4d26d.png)

こちらも最初の**Bling**が違ってしまっていますし、ハイフンが一つ足りませんが、かなり正解に近いです。

プロンプトに対して高精度ですね。

## An old man wearing a T-shirt that says 'オタク'

ダメ元で日本語も試してみました。

```python
prompt = "An old man wearing a T-shirt that says 'オタク'"
```

最初に試したプロンプトで、**Otaku**を**オタク**と日本語にしてみました。

結果は以下です。

![sd3_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/5020bdf9-d146-9458-7f8d-f9c9416a70c4.png)

そうですよね。うまくいきませんよね。

## おまけ ChatGPTだとどうなるのだろう？

ちなみに、同じ内容を[ChatGPT](https://openai.com/chatgpt/)([GPT-4](https://openai.com/index/gpt-4-research/) / [DALL·E 3](https://openai.com/index/dall-e-3/))で描いてみるとどうなるのでしょうか。せっかくなので試してみました。

どれも以下のように「**下記の文章が示す絵を描いてください。**」という指示に続けて**Stable Diffusion 3**の時と同様の英文を書きました。

![chatgpt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/25b39b1f-ee7b-d9e3-6ee2-d3d3f5a3e6ed.png)

### An old man wearing a T-shirt that says 'Otaku'

![dalle-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/0ffa3972-ec94-5161-5c73-482b5633cd76.png)

### A young Japanese woman holding a piece of paper that says 'Touken Ranbu'

![dalle-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/83f3884b-c4e9-d1c4-4462-63177ff3f16c.png)

### A sign that says 'In the name of the moon, I shall punish you!'

![dalle-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/d1b09f74-bf16-8249-e827-106bbd9f6ac9.png)

### A screen projected with 'Bling-Bang-Bang-Born'

![dalle-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/7016db6e-2f77-26d7-4479-3f27079391cc.png)

### An old man wearing a T-shirt that says 'オタク'

![dalle-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869934/4291b2af-b893-bd00-6e2b-686206f64f3f.png)

試行回数が少ないので参考程度ですが、アルファベットについてはプロンプトに近いです。すごいですね。
ただ、文字の反映に関しては**Stable Diffusion 3**の方がやや正確性が高そうです。

## 最後に

文字入れだけなら現時点で他にもっと正確な手段がいくつもあるかもしれませんが、Web APIでしかもプロンプトのみで完結するのはかなり魅力的です。

今後、正確性も網羅性も高くなっていくと思うので、楽しみです。

## 宣伝

[SupershipのQiita Organization](https://qiita.com/organizations/supership-inc)を合わせてご覧いただけますと嬉しいです。他のメンバーの記事も多数あります。

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