Ultralytics YOLO27: ウェイトリストに登録する。
Get Started
レッスン初級

動画で推論を実行する

YOLO26を動画ファイルやライブカメラで実行し、メモリ使用量を一定範囲内に保ちながら、オブジェクトを追跡してそれぞれを一度だけ数え、モデルがフレームレートに追いつけるか確認します。

デプロイされたビジョンシステムの多くは、コンベヤー、ドア、道路に設置されたカメラなどで動画を監視します。動画には、静止画像にはない問題が2つあります。メモリ: 長時間の録画をRAMに保持することはできません。ID: 検出器は同じ人物を60フレームで検出すると、60人として報告します。

このレッスンでは、Predictモードで動画をフレームごとにストリーミングし、オブジェクトトラッキングを追加して各人物を一度だけ数え、独自のカメラループを作成し、モデルが処理に追いつけるかを測定します。

成果

メモリ使用量を一定範囲内に保ちながらYOLO26で動画やカメラをストリーミングし、トラッキングで固有のオブジェクトを数え、フレームあたりの実測ミリ秒数を基に、ソースの処理速度に追いつけるか判断できます。

短期集中コース
すでに使い方をご存じの方は、こちらをご覧ください。
  1. model(video, stream=True)は、メモリ使用量を一定範囲内に保ちながら、フレームごとに1つのResultsを生成します。

  2. model.track(video, stream=True, persist=True, tracker='bytetrack.yaml')はboxes.idを追加します。

  3. オブジェクトの数はIDの集合で数え、最大IDで数えないでください。

  4. 予算 = 1000 ÷ ソースのFPSです。result.speed['inference']と比較してください。

実践的

実践例: 動画ファイルでのPredict#

動画にも画像と同じPredictモードを使用します。この62フレームのクリップには、アトリウムを横切る人々が映っています:

yolo predict model=yolo26n.pt source=https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4
video 1/1 (frame 1/62) solutions_ci_demo.mp4: 384x640 22 persons, 27.3ms
...
video 1/1 (frame 62/62) solutions_ci_demo.mp4: 384x640 22 persons, 54.8ms
Results saved to runs/detect/predict
  • frame 1/62: Ultralyticsが動画をデコードし、画像と同じように各フレームを処理します。
  • 22 persons: そのフレーム内の検出結果です。同じ歩行者が各フレームで再び数えられます。
  • 27.3ms ... 54.8ms: マシン上で他に何が動作しているかによって、フレームごとの処理時間は変わります。

注釈付き動画はruns/detect/predict/solutions_ci_demo.mp4です。独自のモデルも同じように動作します。yolo26n.ptをruns/detect/pills_v1/weights/best.ptに置き換えてください。

長時間のソースやライブソースをストリーミングする#

検出結果を処理するコードでは、ストリームをループします。各イテレーションで1フレーム分のResultsを生成し、その後破棄します:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

frames, people = 0, 0
for result in model(source, stream=True, classes=[0], verbose=False):  # one Results object per frame
    frames += 1
    people += len(result.boxes)
print(f"{frames} frames, {people / frames:.1f} people per frame")
62 frames, 22.2 people per frame

同じループは、Webカメラのインデックス(source=0)やrtsp://camera.local/streamなどのカメラURLを受け付け、ストリームが終了するか停止するまで実行されます。フレームを1つおきに処理するには、vid_stride=2を追加してください。このループを使ったブラウザーUIを作成する場合は、Streamlitライブ推論ガイドでループをアプリに組み込む方法を確認できます。

実践例: 各人物を一度だけ数える#

「1フレームあたり22人」ではなく、知りたいのは「何人が通過したか」です。マルチオブジェクトトラッキングはフレーム間でボックスを関連付け、Trackモードは各オブジェクトにboxes.idのIDを付与します:

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"

seen = set()
for result in model.track(source, stream=True, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False):
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique people tracked")
32 unique people tracked

is_trackは、トラックが確定する前のフレームではFalseであり、そのときboxes.idはNoneです。IDを使って数を数えたり、軌跡を記録したり、「このオブジェクトは3秒間ここにいる」といった処理を実装したりできます。

Ultralytics YOLOによる高速道路のトラッキング: すべての車、バス、トラックに永続的なIDラベルと移動軌跡が表示されています

トラッカー速度堅牢性
bytetrack.yaml高速でシンプルオブジェクトが一時的に見えなくなると、IDを失いやすいです
botsort.yaml低速カメラが動いてもIDを維持しやすいです(動き補償を使用します。外観によるReIDはwith_reidでオプトインします)

trackerを省略すると、Ultralyticsは現在のデフォルトであるtracktrack.yamlを使用します。Trackモードにはocsort.yaml、deepocsort.yaml、fasttrack.yamlも含まれています。トラッカーの選択と調整、さらにトラッカーを使ったオブジェクトカウント、ヒートマップ、速度推定の実装については、ByteTrack、BoT-SORT、TrackTrackでオブジェクトを追跡するで説明しています。

実践例: 独自のカメラループ#

実際のアプリケーションでは、フレームを独自に読み込んで、サイズ変更、クロップ、タイムスタンプ付与、他のコードとのカメラ共有などを行い、各フレームをモデルに渡すことがよくあります。この場合、呼び出し間でトラッカーを維持するのがpersist=Trueです:

import cv2

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
cap = cv2.VideoCapture("solutions_ci_demo.mp4")  # saved locally by the commands above; or 0, or an rtsp:// URL

seen = set()
while cap.isOpened():
    ok, frame = cap.read()
    if not ok:
        break
    result = model.track(frame, persist=True, classes=[0], tracker="bytetrack.yaml", verbose=False)[0]
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
cap.release()
print(f"{len(seen)} unique people, highest ID {max(seen)}")
32 unique people, highest ID 67

track.pyと同じ32人です。最大IDは32ではなく67です。トラッカーは、確定されない仮トラックにもIDを割り当てるため、IDには欠番が生じます。

ソースの処理速度に追いつく#

30 FPSのカメラは33ミリ秒ごとにフレームを出力し、実効フレームレートはデコード、推論、書き込みのうち最も遅い処理によって決まります。ノートPCのCPUでは、実行ごとにマシン上で他に何が動作しているかによって、yolo26nの処理時間は384×640フレームあたり26~46ミリ秒でした。予算と同等か超過しており、余裕はありません。処理が追いつかない場合は、次の方法を順番に試してください:

調整方法効果
小さいモデル(sではなくn)多くの場合、2~3倍高速になります
imgszを小さくする(640ではなく480)ピクセル数と計算量が減ります。小さいオブジェクトほど先に影響を受けます
vid_stride=2処理量が半分になります。動きの遅いシーンに適しています
GPUまたは最適化されたエクスポート最も大きな効果が得られます。NVIDIA上のTensorRTエンジン、またはINT8を使用してください。次のレッスンを参照してください

複数のカメラを同時に扱う方法と、それに伴うスレッド処理については、マルチストリーム推論で説明しています。

次の間違いに注意する#

stream=Trueを忘れる

症状: 長時間の録画では、プロセスがクラッシュするまでメモリ使用量が増え続けるか、ライブカメラの呼び出しが戻らなくなります。 原因: これを指定しないと、Python の呼び出しは戻る前に各フレームの Results オブジェクトを収集します。 対処: stream=True を渡し、反復処理されるまで何も実行しないジェネレーターをループ処理します。

独自のループでpersist=Trueを忘れる

症状: persist=True を指定せずに cv2_loop.py を実行したところ、カウントが27に減り、最大IDも27になりました。IDがフレームごとにリセットされていたため、「ユニーク」カウントは最も混雑したフレームの数にすぎませんでした。対処: フレームごとに track を1回呼び出す場合は、persist=True を渡してください。

最大IDでカウントする

症状: 32人に対してカウントが67になります。原因: 未確定のトラックがあるため、IDに欠番が生じます。対処: track.py の例のように、IDのセットのサイズを数えてください。

トラッカーを明示的に指定する

デフォルトのトラッカーはリリースによって変わる場合があります。tracker="bytetrack.yaml"(または任意のトラッカー)を渡すと、バージョン間でカウントを比較できます。

試してみる

解答にあるtrack_any.pyをデモクリップで実行し、次に短い独自の動画で実行してください。固有オブジェクト数、フレームあたりの平均推論時間(ミリ秒)、その時間がソースのフレーム時間内に収まるかどうか、収まらない場合に最初に試す調整方法を、3行のレポートにまとめてください。yolo track ... save=Trueを使って注釈付き出力を1つ保存し、オクルージョン中にIDが安定しているか記録してください。IDがちらつく場合は、tracker=botsort.yamlを試してください。

完了条件
以下のすべてを満たすと、レッスンは完了です。
  • yolo predictまたはyolo trackから注釈付き動画を保存しました。

  • ストリーミングスクリプトが、boxes.id値の集合から固有オブジェクト数を出力します。

  • フレームあたりの実測時間(ミリ秒)をソースのフレーム時間と比較し、最初に試す速度改善策を挙げました。

解答を表示
import sys

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
seen, times = set(), []
for result in model.track(sys.argv[1], stream=True, persist=True, tracker="bytetrack.yaml", verbose=False):
    times.append(result.speed["inference"])
    if result.boxes.is_track:
        seen.update(result.boxes.id.int().tolist())
print(f"{len(seen)} unique objects, {sum(times) / len(times):.1f} ms inference per frame")

python track_any.py your_video.mp4を使って実行してください。

32 unique objects, 30.5 ms inference per frame (26-46 ms across runs on a laptop CPU)
Source is 30 FPS -> 33 ms budget: fits only on a quiet machine, with no headroom
First lever: export to OpenVINO or ONNX for this CPU, then vid_stride=2 if still short
次のステップ

Pythonで画像や動画に対してモデルを実行できるようになりました。最後に、実運用環境のランタイムで読み込める形式にエクスポートします。