注釈

こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 Enthusiast Community on Facebookへようこそ!他の愛好家と一緒に、Raspberry Pi、Arduino、ESP32の世界により深く入り込みましょう。

参加する理由

  • 専門家サポート: 購入後の問題や技術的な課題を、コミュニティと私たちのチームの助けを借りて解決します。

  • 学習と共有: ヒントやチュートリアルを交換して、スキルを向上させましょう。

  • 限定プレビュー: 新製品の発表や先行プレビューに早期アクセスできます。

  • 特別割引: 最新製品を特別割引でお楽しみいただけます。

  • 季節限定キャンペーンとプレゼント: プレゼント企画やホリデーキャンペーンに参加しましょう。

👉 一緒に発見し、創造する準備はできましたか? [こちら] をクリックして、今すぐ参加しましょう!

1. Raspberry PiでのYOLOの実行

YOLO(You Only Look Once)は、その速度と精度で知られる革新的な物体検出アルゴリズムです。物体検出を回帰問題に変換し、1回のニューラルネットワークの推論で画像内のすべての物体カテゴリと位置を予測します。

「一目で全てを把握する」画像処理システムを想像してみてください。監視カメラ、自動運転、産業用品質管理など、リアルタイムの物体検出が必要とされるあらゆる場面でYOLOは活躍しています。

../_images/yolo_new.png

図:Raspberry Pi上でのYOLOv8nのリアルタイム実行。カメラ画像内の物体が正確に検出・注釈付けされ、検出されたクラスと信頼度が左側に表示されています。この画像は、モデルが人、椅子、テレビなどの物体を正常に識別している様子を示しています。

核となる原理

古い2段階の手法(R-CNNなど)が「まず候補領域を見つけ、それから識別する」のに対し、YOLOは根本的に異なるアプローチを取ります:

  • 統一されたフレームワーク:画像をグリッド(例:元の7x7グリッド)に分割します。

  • グリッドベースの予測:各グリッドセルは、そのセル内に中心がある物体の予測を担当します。各セルは、複数のバウンディングボックス(位置とサイズを含む)とその信頼度を予測し、さらに物体クラスの確率も予測します。

  • ワンステップ処理:分類と位置特定を同じニューラルネットワーク内で同時に実行するため、まさに「You Only Look Once」を実現し、速度において従来の手法を大幅に上回ります。

コードの実行

cd ~/ai-lab-kit/yolo
python3 yolo_test.py

このコードは自動的にモデル(約6 MB)をダウンロードし、カメラで実行します。結果は「YOLOv8」というタイトルのウィンドウに表示されます。

(初回起動時には、約6 MBのモデルが自動的にダウンロードされます):

#!/usr/bin/env python3
import cv2
from picamera2 import Picamera2
from ultralytics import YOLO

model = YOLO("yolov8n.pt")  # ナノモデル

# カメラの初期化
picam2 = Picamera2()
picam2.preview_configuration.main.size = (640, 480)
picam2.preview_configuration.main.format = "RGB888"
picam2.configure("preview")
picam2.start()

print("YOLOを開始しました。「q」を押すと終了します...")

try:
   while True:
      # フレームを取得
      frame = picam2.capture_array()

      # YOLOを実行し、imgsz=320を設定
      results = model(frame, imgsz=320)

      # 結果を描画
      annotated = results[0].plot()

      # 結果を表示
      cv2.imshow("Raspberry PiでのYOLO", annotated)

      # 「q」を押すと終了
      if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
   cv2.destroyAllWindows()
   picam2.stop()
   print("終了しました")

トラブルシューティング

Q: Numpy.dtypeのサイズ変更に関するエラー

Numpyのバージョンをリセットします:

# バージョン2.xの場合は、1.xにリセット
pip3 install "numpy<2.0" --break-system-packages --force-reinstall

Q: libopenblas.so.0 が見つからないエラー

OpenBLASライブラリをインストールします:

sudo apt install libopenblas-dev

Q: カメラを開けないエラー

カメラの接続を確認し、有効になっていることを確認します:

sudo raspi-config
# Interface Options -> Camera -> Enable を選択

Q: メモリ不足によるエラー

スワップ領域を拡張します:

sudo dphys-swapfile swapoff
sudo nano /etc/dphys-swapfile
# CONF_SWAPSIZE=2048 に変更
sudo dphys-swapfile setup
sudo dphys-swapfile swapon

パフォーマンス最適化手法

Raspberry Pi(4B/5でも)でYOLOを動作させるのは負荷が高い場合があります。以下に、いくつかの実証済みの最適化手法を示します:

  1. YOLO推論解像度の調整:上記のコードではすでに imgsz=320 を使用しており、これはバランスの取れた設定です。調整可能な値:

    • imgsz=224 - 最低解像度、最高速度

    • imgsz=320 - デフォルト設定

    • imgsz=416 - より高い精度、低速

    • imgsz=640 - 最高精度、Raspberry Pi上では非常に低速

  2. 適切なモデルの選択

    • yolov8n.pt (6 MB) - 最速、リアルタイム検出に適しています

    • yolov8s.pt (22 MB) - やや遅いが、より正確

    • yolov8m.pt (49 MB) - 低速だが、より高い精度

    • yolov8l/x.pt - Raspberry Pi上では通常使用不可

    • 自分でトレーニングしたモデル(例:"/home/pi/my_model.pt")も使用できます。独自モデルのトレーニング方法については、後の章で説明します。

  3. 検出クラスの制限:特定の物体のみを検出する場合(例:人のみ)、コードを変更します:

results = model(frame, classes=[0], imgsz=320)  # 0は人のクラスID

一般的なクラスID:

  • 0 - 人

  • 1 - 自転車

  • 2 - 車

  • 3 - バイク

  • 5 - バス

  • 7 - トラック

  1. 軽量モデルバリアントの使用

# YOLOv8nの枝刈りバージョンを使用(利用可能な場合)
model = YOLO("yolov8n.pt")

# またはTensorRTアクセラレーションを使用(追加設定が必要)
# model = YOLO("yolov8n.pt")
# model.export(format="engine")  # TensorRTエンジンとしてエクスポート
  1. 画像処理レートの低減:すべてのフレームをリアルタイム表示する必要がない場合は、画像を間欠的に処理します:

frame_count = 0
while True:
    frame = picam2.capture_array()

    # 3フレームに1回処理
    if frame_count % 3 == 0:
        results = model(frame, imgsz=320)
        annotated = results[0].plot()
        cv2.imshow("Raspberry PiでのYOLO", annotated)

    frame_count += 1

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
  1. マルチスレッドの使用:カメラキャプチャとYOLO推論を別々のスレッドに分離します:

import threading
import queue

frame_queue = queue.Queue(maxsize=2)
result_queue = queue.Queue(maxsize=2)

def capture_frames():
    while True:
        frame = picam2.capture_array()
        if frame_queue.full():
            frame_queue.get()
        frame_queue.put(frame)

def process_frames():
    while True:
        frame = frame_queue.get()
        results = model(frame, imgsz=320)
        annotated = results[0].plot()
        if result_queue.full():
            result_queue.get()
        result_queue.put(annotated)

# スレッドを開始
threading.Thread(target=capture_frames, daemon=True).start()
threading.Thread(target=process_frames, daemon=True).start()

while True:
    if not result_queue.empty():
        cv2.imshow("Raspberry PiでのYOLO", result_queue.get())
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

高度な応用

ビデオファイルを入力として使用

import cv2
from ultralytics import YOLO

model = YOLO("yolov8n.pt")
cap = cv2.VideoCapture("input_video.mp4")

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    results = model(frame, imgsz=320)
    annotated = results[0].plot()
    cv2.imshow("YOLO検出", annotated)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

まとめ

このチュートリアルを通して、以下を学びました:

  • Raspberry Pi上にYOLO環境をセットアップする方法

  • カメラを使用してリアルタイム物体検出を実行する方法

  • 一般的なインストールおよび実行時の問題を解決する方法

  • 検出パフォーマンスを最適化するためのさまざまな方法

YOLOの強みはそのシンプルさと効率性にあり、Raspberry Piのような組み込みデバイス上でも十分な物体検出性能を実現します。さらに実験を進めることで、スマート監視、物体追跡、人数カウントなど、さまざまな興味深いアプリケーションを開発できます。