ウェブカメラで1枚撮影してLLaVAに何が写っているか説明してもらう

Takuya Kobayashi⛰
2024.05.25

タイトルの通り、ウェブカメラで1枚撮影して、何が写っているかをAIに説明させるpythonを書いてみました。(というのは嘘で、ほぼGPT-4oが書きました)
自分は命令とコピペとちょっとした修正をしただけです。

完成品はこちら

ファイル名:shot.py

import cv2
import ollama
import base64
from datetime import datetime

def take_photo():
    cap = cv2.VideoCapture(0)

    if not cap.isOpened():
        print("カメラが正常に開けませんでした。")
        return None

    ret, frame = cap.read()

    if not ret:
        print("フレームを取得できませんでした。")
        return None

    current_time = datetime.now()
    file_name = current_time.strftime("%Y%m%d-%H%M%S") + ".jpg"

    cv2.imwrite(file_name, frame)
    cap.release()

    print("写真を撮影しました。ファイル名:", file_name)
    return file_name

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

if __name__ == "__main__":
    file_name = take_photo()
    if file_name is not None:
        encoded_image = encode_image(file_name)
        response = ollama.chat(
            model="llava",
            messages=[
                {
                    "role": "user",
                    "content": "Describe the image in detail:",
                    "images": [encoded_image]
                },
            ],
        )
        print(response["message"]["content"])
    else:
        print("画像の撮影に失敗しました。")

必要なパッケージのインストール

pip install opencv-python ollama

Ollamaをインストール済み前提で話を進めていきます。インストールしてない方は次の記事をご確認ください。

shot.pyの実行と出力

ノートPCのインカメで自撮りをしてみました。

$ python3 shot.py
写真を撮影しました。ファイル名: 20240525-163531.jpg
The image appears to be a low-resolution photograph of an adult male with short hair, giving a thumbs up gesture. He is wearing a dark-colored shirt and has a slight smile on his face. In the background, there is a room with various objects scattered around, including what looks like a desk or tabletop with books and papers. There's also a window with curtains partially drawn. The man is looking directly at the camera, suggesting he may be posing for the photo.

日本語に訳すと:

この画像は、親指を立てるジェスチャーをしている、短髪の成人男性の低解像度の写真のようです。彼は暗い色のシャツを着ており、顔にはわずかな笑みを浮かべています。背景には、本や書類が置かれた机やテーブルのようなものを含む、さまざまな物体が散らばっている部屋があります。部分的にカーテンが引かれた窓もあります。男性はカメラを直接見つめており、写真を撮るためにポーズをとっている可能性があることを示唆しています。

不気味すぎるほど正確です。ポーズから表情、部屋が少し汚いところまでAIに理解されています。
GTX1050Ti 4GBという今や化石レベルのGPUですが、撮影からテキスト生成まで30秒もかかりません。私が同じことをやれと言われても30秒でこれほどの作文はできません。

具体的に何をやっているのか

私は次の2つのプログラムをGPT-4oに書かせました。

  1. ウェブカメラで1枚撮影し、YMD-hhmmss.jpgの形式で保存する
  2. Ollamaに接続してllavaに画像の説明を求める

1.ウェブカメラで1枚撮影

「ウェブカメラで画像を1枚撮影し、YMD-hhmmss.jpgの形式で保存するpythonを書いて」と投げたところ、完璧なプログラムが出力されました。大したものではないので内容は割愛します。

2.Ollamaに接続してllavaに画像の説明を求める

OllamaのpythonパッケージでOllama APIに接続できるようです。

pip install ollama

Usageにあるコードをそのままコピペ。これをもとに編集します。

import ollama
response = ollama.chat(model='llama3', messages=[
  {
    'role': 'user',
    'content': 'Why is the sky blue?',
  },
])
print(response['message']['content'])

こちらを見ると「images:[ファイルパス]」または「images:[base64エンコードした画像データ]」で画像が送れるようなのでbase64にする方に書き換え↓

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

encoded_image = encode_image(file_name)
response = ollama.chat(
    model="llava",
    messages=[
        {
            "role": "user",
            "content": "Describe the image in detail:",
            "images": [encoded_image]
        },
    ],
)
print(response["message"]["content"])

そしてほとんどコーディングせずでできたのが最初に上げたshot.pyです。

llavaの画像の認識精度はとても高く、人の表情から色彩やその他背景情報など加味して推論をしてくれます。これをcrontabで一定時間おきに回したり、sshで出先から実行して異変がないかをAIに確認させたり色んな運用ができそうです。

AIに景色を説明させる

AIに色んなものを見せてやりたいという気持ちが湧いたので、AIを連れて近所の山城跡に行ってみました。

アングルをきめてpythonを実行。
AIによる説明はこちら(日本語訳):

画像は石畳の小道のある田舎の風景を描写しています。 道は画像の中央に向かっており、両側には低い石壁が並んでいます。 この壁は長方形の石でできており、一部は植物に覆われています。

通路の地面は土の色が混ざっており、草や小さな石が散らばっているのが見えます。 通路の周りの環境は緑豊かで青々としており、晩春か初夏であることを示唆しています。 木々は通路の両側に見え、自然な境界線を作り出し、全体的な静けさを醸し出しています。

後方には、ひび割れが見られ、石がいくつか欠けている荒廃した石壁がもう一つあります。 この壁は通路から離れた場所にあり、通路にある壁よりも管理が行き届いていないようです。 上空の空は曇っており、直接の太陽光は見えず、シーン全体に落ち着いた光が当たっています。

画像にはテキストは表示されておらず、画像は自然な色合いでリアルなスタイルです。 写真は低い位置から石畳の小道を見上げて撮影されており、遠くに消えていくにつれてその長さが強調されています。

AIに詩を書かせる

プロンプトの部分を「Describe the image in detail:」→「Write a poem based on the scene you see:」に変更して実行。

AIによる詩はこちら(日本語訳):

静寂に包まれた世界の片隅、 石畳の小道が誘う、静かな旅路。 自然の導きによって、 山野を縫い、迷いながら進む。

木々に葉はなく、 秋の静寂、穏やかな音。 陽光は高い樹冠を透けて降り注ぎ、 目の前の小道を照らす。

素朴な橋が小川にかかる、 夢の中で過去のささやきが聞こえる。 その石は数え切れないほどの年月を目撃し、 終焉が現れるまで堅実に立っている。

森の床には秋が絨毯のように敷き詰められ、 魂が這うための絨毯のよう。 古い木々と深い影の中、 平和を求める人々を招き入れる。

内蔵ウェブカメラの画質が悪いので解釈違いをしている部分もありますが、詩のクオリティは素晴らしいですね。プロンプトにペルソナやその他の情報を付与すればもっとリアルな詩が書けそうです。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です