PCのカメラから人物を推定してその物体の座標をMQTTで送る 3/3

「PCカメラから人物を推定してその物体の座標をMQTTで送る」アプリケーションをPythonで作成しております。

↓ 記事の一覧はこちら

PCのカメラから人物を推定してその物体の座標をMQTTで送る その1

PCのカメラから人物を推定してその物体の座標をMQTTで送る その2

結果

こちらが表示画面。

Node-REDでの出力です。

Object: 検出された物体名

confidence : 確度

center_x : 物体のx座標

center_y : 物体のy座標

と、欲しかった結果が表示されています。

やったこと

PCのカメラから人物を推定してその物体の座標をMQTTで送る その1 と PCのカメラから人物を推定してその物体の座標をMQTTで送る その2 のコードをChatGPTに入れて生成してもらいそれを実行しただけです。

コードは下記のとおり

import cv2
import torch
import paho.mqtt.client as mqtt
import time
import json

# YOLOv5 のモデルをロード
model = torch.hub.load("ultralytics/yolov5", "yolov5s", pretrained=True)

# MQTT ブローカー設定
BROKER = "public.cloud.shiftr.io"  # Shiftr.ioのブローカー
PORT = 1883
TOPIC = "pythontest"
USERNAME = "public"
PASSWORD = "public"

# MQTT クライアントの作成
client = mqtt.Client()
client.username_pw_set(USERNAME, PASSWORD)
client.connect(BROKER, PORT, 60)

# USBカメラを起動
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("カメラが開けませんでした。")
    exit()

while True:
    ret, frame = cap.read()
    if not ret:
        print("フレームの取得に失敗しました。")
        break

    # YOLOv5 でオブジェクトを検出
    results = model(frame)
    df = results.pandas().xyxy[0]  # pandas DataFrame で結果を取得

    for _, row in df.iterrows():
        x1, y1, x2, y2, conf, cls = row["xmin"], row["ymin"], row["xmax"], row["ymax"], row["confidence"], row["name"]
        
        # **person以外を除外**
        if cls != "person":
            continue

        # 中心座標を計算
        x_center = int((x1 + x2) / 2)
        y_center = int((y1 + y2) / 2)
        
        # **MQTTでデータ送信**
        data = {
            "object": cls,
            "confidence": round(float(conf), 2),
            "center_x": x_center,
            "center_y": y_center
        }
        client.publish(TOPIC, json.dumps(data))
        print(f"Sent MQTT: {data}")

        # バウンディングボックスを描画
        cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
        cv2.circle(frame, (x_center, y_center), 5, (0, 0, 255), -1)
        text = f"{cls} ({x_center}, {y_center}) {conf:.2f}"
        cv2.putText(frame, text, (x_center + 10, y_center - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 255), 2)

    # 映像を表示
    cv2.imshow('Camera', frame)

    # 'q' を押したら終了
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# リソースの解放
cap.release()
cv2.destroyAllWindows()
client.disconnect()

まとめ

以上で「PCカメラから人物を推定してその物体の座標をMQTTで送る」というアプリケーションが完成しました。データはNode-REDで受けているので、このデータをもとに照明や空調などの設備と連携することも可能です。

それにしても、ChatGPTを使って今回のアプリケーションを作成しましたが、拍子抜けするほど簡単にできました。

数年前にWinPC上でOpenCVを使ったときは環境構築だけでものすごく大変だった記憶があるのですが、エラーが発生した場合に、そのままChatGPTに投げると適切に対応方法を指示してくれるので問題解決にかかる時間が圧倒的に短縮されました。

便利な時代になりましたね。

次回は映像ソースをPCの内蔵カメラから監視カメラなどのRTSPにするような修正をする予定です。