柿ピーで学ぶGPT-4V(OpenAI Vison API)


# はじめに
昨日の記事「[DALL·E APIで実在しないポケモンを創る](https://qiita.com/Isaka-code/items/7eba1881931dd646baed)」に引き続き、OpenAI APIを扱います。
本日のお題は、「**柿ピーで学ぶGPT-4V(OpenAI Vison API)**」です。

**GPT-4V(OpenAI Vison API)**

https://platform.openai.com/docs/guides/vision

**柿ピーとは**
>菓子としての「柿の種（かきのたね）」は、日本生まれの米菓のうち、あられ、かき餅の一種。唐辛子の辛味を利かせた醤油味の、長楕円形・粒状のあられで、色・形ともにカキノキ（柿木）の種子に似ていることからその名で呼ばれる。

>味付けの異なる様々な派生商品が開発されているが、ごく一部の甘い商品を例外として、辛味の強い菓子である。形にバリエーションは無い。剥き身のピーナッツと組み合わせたものは「柿ピー」の名で親しまれており、旧来の柿の種と並び、広く普及している。

出典：[Wikipedia/柿の種](https://ja.wikipedia.org/wiki/%E6%9F%BF%E3%81%AE%E7%A8%AE)


題材の柿ピー画像データは下記のリンクに置いています。

```
https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/5a1a7f3f-851b-4673-d6e5-d3ad51621be7.png
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/5a1a7f3f-851b-4673-d6e5-d3ad51621be7.png)



# GPT-4V(OpenAI Vison API)
まずは、公式ドキュメントに沿って進め、GPT-4V(OpenAI Vison API)の使い方を理解します。
前提として、[OpenAI APIの使い方講座【公式Quickstart】](https://qiita.com/Isaka-code/items/b50983796636503b44c5)のStep2まで完了している必要があります。
続きのStep3の代わりに、下記のページから始めます。

https://platform.openai.com/docs/guides/vision

まずは**Quick start**のソースコードを動かします。

```python
from openai import OpenAI

client = OpenAI()

response = client.chat.completions.create(
  model="gpt-4-vision-preview",
  messages=[
    {
      "role": "user",
      "content": [
        {"type": "text", "text": "What’s in this image?"},
        {
          "type": "image_url",
          "image_url": {
            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg",
          },
        },
      ],
    }
  ],
  max_tokens=300,
)

print(response.choices[0])
```

このソースコードでは、Wikipediaのとある写真を題材に、プロンプト`What's in this image?`を用いて、GPT-4Vに画像を説明させます。

**実行結果例**
>Choice(finish_reason=None, index=0, message=ChatCompletionMessage(content='The image shows a picturesque outdoor scene featuring a wooden boardwalk extending through a lush green field. The boardwalk provides a path over the dense grass, facilitating access across the area. The sky is partly cloudy, suggesting pleasant weather conditions, and the light from the sun casts a warm glow over the landscape, enhancing the vivid green hues of the flora. Trees are visible in the background, dotting the horizon line, and the overall impression is of a tranquil natural setting, possibly a nature reserve or a park where people can enjoy a walk and connect with the environment.', role='assistant', function_call=None, tool_calls=None), finish_details={'type': 'stop', 'stop': '
'})

**翻訳**
>画像は、緑豊かな野原に木製のボードウォークが伸びている、絵のように美しい屋外の風景。ボードウォークは鬱蒼と茂る草の上に道を提供し、エリア全体へのアクセスを容易にしている。空は部分的に曇っており、心地よい天候であることを示唆している。太陽の光は風景に暖かい輝きを投げかけ、植物の鮮やかな緑色を引き立てている。背景の地平線には点々と木々が見え、全体的な印象は静かな自然環境、おそらく自然保護区か、人々が散歩を楽しみ、環境とつながることのできる公園であろう。


以上で公式ドキュメントの内容は終了です。



# 本日のお題①：GPT-4V(OpenAI Vison API)で柿ピーを説明させる
**出来上がったソースコード**
```image_recognition.py
from openai import OpenAI

def recognize_image(image_url, prompt):
    client = OpenAI()
    response = client.chat.completions.create(
        model="gpt-4-vision-preview",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {
                        "type": "image_url",
                        "image_url": {"url": image_url},
                    },
                ],
            }
        ],
        max_tokens=300,
    )
    return response.choices[0]

if __name__ == "__main__":
    image_url = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/5a1a7f3f-851b-4673-d6e5-d3ad51621be7.png"
    prompt="この画像を説明して"

    result = recognize_image(image_url, prompt)

    print(result)
```

公式ドキュメントのサンプルコードをベースにしていますが、下記の変更を行いました。
- 関数化し、入力を汎用的に変更できるようにしました。
- データのURLを柿ピーに変更しました。
- 課題を達成するために、`この画像を説明して`を`prompt`として与えています。


**実行結果**

>Choice(finish_reason=None, index=0, message=ChatCompletionMessage(content='画像には、白い背景の上に散らばっている複数の種子が写っています。種子は2種類の色と形状があります。オレンジ色で光沢があり、クロワッサンのような形をした
種子が多数あり、これはおそらく塩漬けや味付けされたカボチャの種かひまわりの種の可能性があります。もう一方の種子は淡い黄色をしており、もっと扁平で、生のかぼちゃの種または何らかのナッツの種のように見えます。なお、これらの種子は 食用である可能性が高いです。', role='assistant', function_call=None, tool_calls=None), finish_details={'type': 'stop', 'stop': '
'})

食べ物であることや、２種類あるということは認識しました。ただ、柿ピーに対する事前知識が無いのか、正確な説明では無さそうです。


# 本日のお題②：GPT-4V(OpenAI Vison API)で柿ピーを数える
**出来上がったソースコード**
```image_recognition.py
from openai import OpenAI

def recognize_image(image_url, prompt):
    client = OpenAI()
    response = client.chat.completions.create(
        model="gpt-4-vision-preview",
        messages=[
            {
                "role": "user",
                "content": [
                    {"type": "text", "text": prompt},
                    {
                        "type": "image_url",
                        "image_url": {"url": image_url},
                    },
                ],
            }
        ],
        max_tokens=300,
    )
    return response.choices[0]

if __name__ == "__main__":
    image_url = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627015/5a1a7f3f-851b-4673-d6e5-d3ad51621be7.png"
    prompt="柿ピーを数えて"

    result = recognize_image(image_url, prompt)

    print(result)
```

先程のソースコードをベースにしていますが、下記の1点のみ変更を行いました。
- 課題を達成するために、`柿ピーを数えて`を`prompt`として与えています。


**実行結果**

>Choice(finish_reason=None, index=0, message=ChatCompletionMessage(content='この画像には、柿の種とピーナッツが混じった「柿ピー」と呼ばれる日本のスナックが写っています。柿の種は黄色い部分で、ピーナッツは色が薄い部分です。\n\n柿の種を数えると、19個あります。ピーナッツを数えると、9個です。合計では、柿ピーが28個あります。', role='assistant', function_call=None, tool_calls=None), finish_details={'type': 'stop', 'stop': '
'})

いくつか数え漏れがあるのか、実際の数よりも少な目になってしまいました。


# おわりに

この記事では、柿ピーを題材にゼロショットで①画像認識、②物体検出を行いました。
題材の柿ピーは日本特有のお菓子なので結果は微妙でしたが、学習データなしでここまでできるのは便利になりましたね。


:::note info
柿ピーはスタッフが美味しく頂きました😋
:::



### ソースコード

本記事で使用したソースコードは、下記のGitHubレポジトリに格納しています。

https://github.com/Isaka-code/openai-api-hands-on