さっそくGradioでGPT-4oのAPIを使って画像を説明させるアプリを作ってみた


:::note info
2024/5/14
画像の処理に問題があり、色情報が正しくgpt-4oに伝わってなかったのでコードを修正
:::

## はじめに

　もうすでにたくさんの人が使っているようですが、本日公開されたGPT-4oのAPI(OpenAI)を使って画像を説明させるアプリを作ってみました。

 ## 料金

 　APIにかかる料金はこんな感じです。(2024/5/14現在)

  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/444e66a5-40ff-1959-75a9-0ed06f1a402b.png)

  GPT-4Turboより安価で高速、2023年10月までの知識を持っているようです。

## 準備

opencv-python, gradio, openaiあたりをpipでinstallしておいてください。


## ソースコード

　ソースコードは以下になります。secret.jsonに取得したAPIキーを入れてください。OSの環境変数から読み込みたい人は適宜ソースコードを修正してください。

```secret.json
{
    "OPENAI_API_KEY": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
```

　pythonコードはこちら、SYSTEM_ROLE_CONTENTとPROMPT_TEMPLATEを書き換えることで、処理内容を変えることができます。

```gr_gpt4o_image.py
# gradioでChatGPTを使って画像を文章で説明するプログラム
import base64
import io
import json
from PIL import Image
import gradio as gr
from openai import OpenAI

SYSTEM_ROLE_CONTENT = "このシステムは提供された画像の内容を説明を生成します。画像を識別し視覚情報をテキスト形式で提供します。"
PROMPT_TEMPLATE = "画像を日本語で説明してください。"

def get_gpt_openai_apikey():
    with open("secret.json") as f:
        secret = json.load(f)
    return secret["OPENAI_API_KEY"]


def encode_image(image):
    byte_arr = io.BytesIO()
    image.save(byte_arr, format='JPEG')
    base64_image = f"data:image/jpeg;base64,{base64.b64encode(byte_arr.getvalue()).decode()}"
    return base64_image

def create_message(system_role, prompt, image_base64):
    message = [
        {
            'role': 'system',
            'content': system_role
        },
        {
            'role': 'user',
            'content': [
                {
                    'type': 'text',
                    'text': prompt
                },
                {
                    'type': 'image_url',
                    'image_url': {
                        'url': image_base64
                    }
                },
            ]
        },
    ]
    return message


def gen_chat_response_with_gpt4(image):
    openai_client = OpenAI(api_key=get_gpt_openai_apikey())
    image_base64 = encode_image(image)
    messages = create_message(SYSTEM_ROLE_CONTENT, PROMPT_TEMPLATE, image_base64)

    response = openai_client.chat.completions.create(
        model='gpt-4o-2024-05-13',
        messages = messages,
        temperature = 0.1,
    )

    # print(response)
    return response.choices[0].message.content



def main():
    
    image = gr.Image(label="画像ファイル", type="pil")
    output = gr.Textbox(label="説明")

    gr.Interface(fn=gen_chat_response_with_gpt4, inputs=image, outputs=output).launch()

if __name__ == "__main__":
    main()
```


## アプリの起動

　ターミナルより以下を実行

 ```
python gr_gpt4o_image.py
 ```
 
　こんな感じの出力がきたら、アプリ起動成功。
 
 ```
Running on local URL:  http://127.0.0.1:7860
 ```

　URLにアクセスすると下記の画面が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/339a96db-5f1f-26e8-1146-76eafee50991.png)


## 実行例

　画面右に画像をアップロードして、Submitボタンを押すと画面左に画像の説明文が表示されます。

 ![スクリーンショット 2024-05-14 211812.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/350321/b517e630-4272-45f4-492a-e1ad78439cfc.png)


　※サンプル画像はフリー画像サイト[pixabay](https://pixabay.com/ja/)より取得しました。


## おわりに
　GPT-4oのAPIをさっそく使ってみました。使った肌感として、生成されるテキストはGPT-4 turboよりさらに賢くなった感じで、なにより応答がメチャメチャ早いです。