骨折 or NOT骨折。GPT-4oにレントゲン写真を診断させてみた。

## 骨折しました
先日野球をしている最中、薬指にボールが当たり怪我をしてしまいました。
怪我をした翌日に病院へ行ったところ、骨折していないと診断されました。
そのときのレントゲン写真が下の画像になります。

※画像はレントゲン写真を自分のスマホで撮らせていただいたものです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/be1872fb-5817-9395-3fde-e7a35ff91da9.jpeg" width="400">

しかし、2週間後に病院へ行ったときは、骨折になっていました。
そのときのレントゲン写真が下の画像になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/6bc5ebf4-a34e-aa2b-8196-08ae748a914e.jpeg" width="400"> 

この2週間でどこかに強くぶつけたという記憶もなかったので、最初病院に行った際には、少なくとも骨が折れかけだったのではないかと思っていました。

そこで、今回は画像解析の精度が向上したと言われるGPT-4oを用いて、最初病院に行った際の画像をどのように診断するか確認するため、画像診断をするアプリをstreamlitで実装しました。

## 作成したアプリ
画像をアップロードして画像診断ボタンを押すと、その結果が下に表示されます。

初診のときの画像では、複数骨折していることになっています。また、中手骨とは掌あたりの骨になるので、明らかに間違っていますね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/1ee50144-ca4a-5f58-8e21-740070acf52b.png" width="450"> 


二週間後の画像では、骨折とは診断されていますが、具体的な位置までは回答されませんでした。


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682615/bd42f469-62ca-5090-2416-8e16cc6d3589.png" width="450"> 


## 実装
画像をアップロードし、「画像を診断」ボタンを押すと、OpenAI APIに送信されます。
画像を解析し、「骨折」か「NOT骨折」を判定し、結果が画面に表示されます。


"YOUR OPENAI API KEY"はご自身のものを入力する必要があります。
また、requestsで一時的にverify=Falseオプションを指定していますが、一般的には推奨されません。
```streamlit.py
import streamlit as st
from PIL import Image
import io
import base64
import requests

api_key = "YOUR OPENAI API KEY"

# Streamlitアプリの構築
st.title("骨折 or NOT骨折")

# ファイルのアップロード
file = st.file_uploader("X線画像をアップロードしてください。", type=['png', 'jpg', 'jpeg'])

if file is not None:
    # アップロードされた画像の表示
    image = Image.open(file)
    st.image(image, caption='アップロードされた画像', use_column_width=True)

    if st.button("画像を診断"):
        # 画像をbase64エンコード
        buffered = io.BytesIO()
        image.save(buffered, format="JPEG")
        base64_image = base64.b64encode(buffered.getvalue()).decode('utf-8')

        headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {api_key}"
        }

        payload = {
            "model": "gpt-4o",
            "messages": [
                {
                    "role": "system",
                    "content": "あなたは医者です。"
                },
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "text",
                            "text": "提供された画像について、「骨折」もしくは「NOT骨折」で判断してください。"
                        },
                        {
                            "type": "image_url",
                            "image_url": {
                                "url": f"data:image/jpeg;base64,{base64_image}"
                            }
                        }
                    ]
                }
            ],
            "max_tokens": 300
        }

        response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload, verify=False)

        if response.status_code == 200:
            result = response.json()
            st.write(result['choices'][0]['message']['content'])
        else:
            st.write("APIリクエストに失敗しました。")
```

## まとめ
今回は、GPT-4oを用いて画像診断を行いましたが、思っていたよりもうまくいきませんでした。怪我をしたときは必ず病院へ行くようにしましょう。

また、今回はスマホで取ったレントゲンの画像を用いているため、光の加減で画像が少し白くなっている箇所があったりしました。レントゲン写真そのものを用いれば、結果が変わるような気もするので、試したみたいです。