AI博士に写真レビューさせて、現実でカメラアクションゲームを楽しもう

このように、撮った写真をChatGPTにレビューさせることで、現実世界でカメラアクションゲームのように遊べます。

https://twitter.com/s2terminal_tech/status/1757397122834702669

## OpenAI ChatGPT PlusでGPTsを使う場合
OpenAI ChatGPT Plusに登録していたら下記から使えます。

https://chat.openai.com/g/g-Fja13VvZf-xie-zhen-bo-shi-ai

といっても、やっていることは簡単です。中身はGPTsの高度な機能は使っておらず、アップロードされた写真を所定の口癖でレビューするようpromptで指示しているだけです。ChatGPTは画像ファイルを読み取る事ができ、そのままでも写真の中身を説明させたりできますが、ちょっと工夫するだけでこのように遊べます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/8d7f8cf9-238d-ca73-fbda-13c91ebe64ac.png)

特に高度な機能は何も使っていませんが、これだけでアップロードされた画像をしっかりレビューして、上から目線でコメントをくれるようになります。

<img width=303 src="https://pbs.twimg.com/media/GGOHXphbYAAxrsm?format=jpg&amp;name=large" alt="画像"/>
<img width=303 src="https://pbs.twimg.com/media/GGOHXoPaUAArncW?format=jpg&amp;name=large" alt="画像"/>
<img width=303 src="https://pbs.twimg.com/media/GGOHXq5aMAAvDlc?format=jpg&amp;name=large" alt="画像"/>

私は写真には詳しくないので博士の言っていることが正しいのかどうかはよく分かりません。ですが、少なくとも単なる物体の位置や種類の認識だけでなく、映り方や光の当たり方などまで認識してから建設的なアドバイスをしている事はわかります。

## PythonでOpenAI APIを使う場合
ここからが本題です。先述のGPTsのようなものをアプリケーションとして実装したい場合、[OpenAI Vision API](https://platform.openai.com/docs/guides/vision?lang=python)を使うことで、画像を読み取ってそれについて答えるアプリケーションを構築できます。

なお2024年2月現在Assistants APIではVision APIが使えないので、GPTsにあるようなRetrieval等の機能と組み合わせて使うことはできません。以下のように、Chat Completion APIでのみ使うことができます。

Pythonで、以下のようなコードで画像をレビューさせる博士を実装できます。

```python:python
import base64
import openai

# ※Colab Secretを使う例。環境変数などに適当に書き換え
openai_client = OpenAI(api_key=userdata.get('OPENAI_API_KEY'))

# ※書き換え
image_path = "your_image_path/your_image.JPG"

def encode_image(image_path):
  with open(image_path, "rb") as image_file:
    return base64.b64encode(image_file.read()).decode('utf-8')

base64_image = encode_image(image_path)

PROMPT = """- あなたは写真にとても詳しい博士です。アップロードされた写真をレビューします
- 「今回はどんな写真を撮ってきたんじゃ？」と言って、どんな写真なのかを説明します
- 写真の良いところを「すばらしい！」と言って褒めます
- 手ブレ、ピント、明るさ、被写体や構図、立体感などに点数を付けます
- 「おしいのぉ・・・」と言ってから具体的なアドバイスをします
- アドバイスは小学生でも分かるよう具体的で分かりやすく
- 「そりゃそうじゃ」が口癖

## 例
どれどれ、今回はどんな写真を撮ってきたんじゃ？
ふむふむ、これは春の川沿いの都市の風景の写真じゃな。季節が感じられて良い写真じゃのう。露出はどうじゃ？明るくてきれいに撮れておるぞ。すばらしい！バッチリじゃ。80点じゃな。
手ブレはどうじゃ？おしいのぉ・・・すこしブレておるようじゃ。カメラをしっかり両手で持ったり、三脚を使って、ブレないようにするのが良いじゃろう。そりゃそうじゃ。また写真の右側が影になっておるぞ。他の物が映らないように、もう少し角度を変えて撮影できれば良かったのぉ。映したいものがいっぱいに映るように、被写体に近づいてみると良いじゃろう。
次はもっと良い写真を期待しておるぞ。
"""

chat_completion = openai_client.with_options(max_retries=5).chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": PROMPT
                },
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/jpeg;base64,{base64_image}",
                        "detail": "low"
                    }
                }
            ]
         }
    ],
    model="gpt-4-vision-preview",
    max_tokens=1000,
)
```

普通にOpenAI APIを使うときと基本は同じです。`model="gpt-4-vision-preview"`と指定して、base64エンコードした画像を所定のフォーマットでメッセージと一緒に載せます。なお、なぜか通常のChat Completionに比べて`max_tokens`のデフォルト値がかなり小さいようで、ある程度大きい値を設定してあげないとまともに動きません。

Vision APIはまだプレビュー版であり、被写体の正確な位置の認識が難しかったり、英語以外の言語で使ったときの性能については適切に動作しない可能性があるとされています。が、私がすこし試した感じでは割と普通に使えているように見えます。

写真に詳しい方は、ぜひpromptを工夫したりして、より適切なアドバイスが出るように工夫してみてください。

### Vision APIでのトークン数の消費
画像もトークン数として換算されており、高解像度な画像を扱うとトークンを多く消費しますが、これを制御できる`detail`オプションがあります。

`"detail": "low"`としていますが、ここを変更することでモデルへの画像の入力サイズを調整できます。高解像度にするとトークン数がかなり大きくなりますが、今回の用途では返答に大きな差が見られなかったため`low`としました。現状の仕様では`low`だと画像部分 85 トークン、`high`だと画像によりますが本稿で挙げた例だと750トークン程度を消費しました。お好みで変更すると良いと思います。

## 参考
- [AIプロ写真家による写真レビューAIボット作りました。｜横田 裕市](https://note.yokoichi.jp/n/n7278fb82230e)
    - AIに写真をレビューさせるというアイデアを参考にしました
- [ポケモンスナップ学会とは \(ポケモンスナップガッカイとは\) \[単語記事\] \- ニコニコ大百科](https://dic.nicovideo.jp/a/%E3%83%9D%E3%82%B1%E3%83%A2%E3%83%B3%E3%82%B9%E3%83%8A%E3%83%83%E3%83%97%E5%AD%A6%E4%BC%9A#h2-1)
    - 一部表現を参考にしました
- [DALL·E 3](https://openai.com/dall-e-3)
    - 博士のアイコン画像を生成しました