画像からプロンプトを考えて最も似ている画像を生成した人が勝ちのゲームやーる

# はじめに
[がちもとさんアドベントカレンダー](https://qiita.com/advent-calendar/2023/gachimoto3)20日目の記事です。

今日は、11日目に公開した[画像からプロンプトを考えて最も似ている画像を生成した人が勝ちのゲーム](https://qiita.com/SatoshiGachiFujimoto/items/fddf546164dc54bcc876)を、エンジニアの輪＠福岡で実際に行ってきたのでその記録になります。

当日の登壇資料はこちらです。

https://speakerdeck.com/satoshirobatofujimoto/hua-xiang-karapuronputowokao-etezui-mosi-teiruhua-xiang-wosheng-cheng-sitaren-gasheng-tinogemu

# 開発環境
- Windows 11 PC
- Python 3.11

# ゲームの流れ
1．お題の画像を用意する
2．画像を見てプロンプトを考える
3．DALLE3で画像生成する
4．お題の画像と生成した画像の類似度（SSIM）で競う

参加者は10名、所要時間は7分程度です。

# お題

今日のお題はこちらです。1分間でプロンプトを考えてください。

|groundtruth.png|
|:--|
|![groundtruth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/325c7074-f11a-3c85-2816-0a9a27f67e59.png)|

# DALLE3で画像生成
こちらのStreamlitの画像生成アプリを用いて、プロンプトを貼り付け、画像生成します。

~~~app.py
import streamlit as st # pip install streamlit
from openai import OpenAI # pip install openai
import requests # pip install requests
import os
import re
from PIL import Image # pip install pillow
from io import BytesIO
from skimage.metrics import structural_similarity as compare_ssim # pip install scikit-image
import numpy as np # pip install numpy

from dotenv import load_dotenv # pip install python-dotenv
load_dotenv(verbose=True)

# Streamlitページの設定
st.title('DALL-E画像生成アプリ')

# 画像を保存するディレクトリの作成
os.makedirs('generated_images', exist_ok=True)

# 基準画像の読み込み
groundtruth_path = 'groundtruth.png'
if os.path.exists(groundtruth_path):
    groundtruth_img = Image.open(groundtruth_path)
    groundtruth_img = groundtruth_img.convert('L')  # グレースケールに変換
else:
    st.error('基準画像が見つかりません。')

# 生成された画像とSSIMスコアを保持するリスト
images_ssim = []

# 複数のプロンプト入力
prompts = st.text_area('複数の画像プロンプトを入力してください（行ごとに異なるプロンプト）').split('\n')

# 生成された画像を保持するリスト
images = []

# プロンプトが入力されたときに画像を生成
for prompt in prompts:
    if prompt:
        # ファイル名をプロンプトから生成
        file_name = re.sub(r'\W+', '_', prompt)[:20] + '.png'

        # OpenAI APIを使用して画像を生成
        try:
            client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
            response = client.images.generate(
                model="dall-e-3",
                prompt=prompt,
                size="1024x1024"
            )

            # 画像のURLを取得
            image_url = response.data[0].url

            # 画像をダウンロードして保存
            response = requests.get(image_url)
            if response.status_code == 200:
                print(file_name, "done")
                path = os.path.join('generated_images', file_name)
                with open(path, "wb") as f:
                    f.write(response.content)

                # PILを使用して画像サイズを調整
                img = Image.open(BytesIO(response.content))
                resized_img = img.resize((150, 150))  # 画像サイズを150x150に調整

                # 画像をリストに追加
                images.append(resized_img)

                img = img.convert('L')  # グレースケールに変換

                # SSIM計算
                ssim = compare_ssim(np.array(groundtruth_img), np.array(img))
                images_ssim.append(ssim)

        except:
            print(file_name, "error")

# 5個ずつ画像を並べて表示
for i in range(0, len(images), 5):
    cols = st.columns(5)
    for j in range(5):
        if i + j < len(images):
            with cols[j]:
                st.image(images[i + j], use_column_width=True, caption=f'{images_ssim[i + j]}')
~~~

~~~.env
OPENAI_API_KEY="<INSERT-YOUR-API-KEY>"
~~~

# 結果

|お題|1|2|3|4|5|
|:--|:--|:--|:--|:--|:--|
|![groundtruth.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/325c7074-f11a-3c85-2816-0a9a27f67e59.png)|![浮島にお城が立っている_ドラゴンが飛び交.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a89ef98a-9982-5ceb-d0d8-f21b5cdd8eeb.png)|![7つの小さな島が宙に浮いている_島には尖.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/56e9571c-1663-da5c-60a7-6e499dca6f00.png)|![雲の上の空が舞台_複数の島が空に浮いてい.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/557cc113-ee6a-cf30-23df-021fa3faa15f.png)|![空に浮かんだ島に_城が立っていて_ドラゴ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/7e8d7f28-46fc-37be-5085-18362f29aec7.png)|![夕陽が見える空中都市に複数のドラゴンが飛.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/17f3f8e2-1585-0a28-f838-f26f200f3160.png)|
||0.153|0.367|0.360|<font color="Red">0.391</font>|0.305|
||**6**|**7**|**8**|**9**|**10**|
||![空に島が浮かんでいて_島にはお城が浮かん.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/ba75bd82-ad66-bd7e-8e9c-06162c1cc572.png)|![ファンタジーの国である_翼の生えたドラゴ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/e60423db-2174-b4db-245b-3dda2da99725.png)|![雲海の上にお城が建築されている島がたくさ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/290096ca-4315-eb96-f56c-4f06c16f4660.png)|![7つの島_ドラゴンが大量に飛んでいる_虹.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5c47c37f-449e-7fff-3e18-0f4f88b1034a.png)|![雲の上に浮かぶ王国の風景です_６つの島が.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/623ffa79-096e-27c7-6efa-f8944b0acbec.png)|
||0.364|0.268|0.297|0.322|0.295|

1．浮島にお城が立っている。ドラゴンが飛び交っている。虹も出てる！ 
2．7つの小さな島が宙に浮いている。島には尖った城が建っていて庭がある。雲の上で奥には虹がかかっている。空にはドラゴンが飛んでいる。
3．雲の上の空が舞台。複数の島が空に浮いている。島には城が立っている。空にはドラゴンが複数体飛翔している。空には夕日が出ており、虹が掛かっている。
<font color="Red">4．空に浮かんだ島に、城が立っていて、ドラゴンが飛んでいて、虹が出ている、明るいファンタージ風の絵</font>
5．夕陽が見える空中都市に複数のドラゴンが飛んでいる
6．空に島が浮かんでいて、島にはお城が浮かんでいて、夕陽があって虹が綺麗で、周りに龍が飛んでいる
7．ファンタジーの国である、翼の生えたドラゴンがうじゃうじゃいます。天空に島が多数浮いています。夕暮れ時で虹がかかっています
8．雲海の上にお城が建築されている島がたくさん浮いている。ドラゴンがたくさん飛んでいる。夕日と虹が出ている
9．7つの島、ドラゴンが大量に飛んでいる。虹がかかっている。天空の城ラピュタが舞台。雲がいっぱい。
10．雲の上に浮かぶ王国の風景です。６つの島が雲の上に浮かんでいます。６つの島にはそれぞれ城がそびえたっています。６つの島の奥にはひときわ大きい島が浮かんでおあり、大きな城がその上に立っています。空にはたくさんのドラゴンが飛び交っています。奥の背景には夕日と虹があります。

# まとめ
優勝は4番目のプロンプトでした！
いかがでしたか？皆さんもやってみてくださいね～