0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

KV260でYOLOv7リアルタイムカメラ物体検出(DPU B4096, 3.6FPS)

0
Posted at

はじめに

Xilinx KV260のDPU(Deep Learning Processing Unit)を使って、USBカメラの映像をYOLOv7でリアルタイム物体検出し、HDMIモニタに結果を表示します。

前回の記事で静止画のYOLOv7推論(190ms, 5.3FPS相当)を実現しましたが、今回はそのxmodelをそのまま流用し、カメラ入力→リアルタイム表示まで仕上げます。

構成

項目 内容
ボード Kria KV260
OS Ubuntu 22.04
DPU DPUCZDX8G_ISA1_B4096 (300MHz)
モデル YOLOv7(PTQ量子化済み)
カメラ USB Webカメラ (UVC, 640x480)
表示 HDMI (cv2.imshow, X11)
Docker vai-yolov7:v2 (Vitis AI runtime + OpenCV GUI)

システム構成図

USB Camera (640x480)
    │
    ▼
┌──────────────────────────────────────────┐
│  Docker (vai-yolov7:v2)                  │
│                                          │
│  CameraThread ──→ 前処理(resize,正規化)  │
│                      │                   │
│                      ▼                   │
│                   DPU推論 (185ms)         │
│                      │                   │
│                      ▼                   │
│                  後処理(decode+NMS, 90ms) │
│                      │                   │
│                      ▼                   │
│                   描画+表示              │
└──────────────────────────────────────────┘
    │
    ▼
HDMI Monitor (バウンディングボックス + FPS表示)

後処理の高速化が鍵

DPU推論は185msで固定ですが、YOLOv7の後処理(アンカーデコード + NMS)がPythonでは非常に重いです。

初期実装: 0.6 FPS

3重forループで全グリッド(80x80 + 40x40 + 20x20 = 25,200セル x 3アンカー)を走査:

# これだとARM Cortex-A53で約1400ms
for ay in range(grid_h):
    for ax in range(grid_w):
        for a in range(3):
            det = out[ay, ax, a]
            obj_conf = sigmoid(det[4])
            if obj_conf < conf_thresh:
                continue
            ...

最終実装: 3.6 FPS(6倍高速化)

2つの最適化を適用:

1. sigmoid事前フィルタ

sigmoid(x) > threshold は x > log(threshold / (1 - threshold)) と数学的に等価。生の値で比較し、通過した検出のみsigmoidを計算する:

raw_thresh = np.log(conf_thresh / (1.0 - conf_thresh))
mask = raw_obj > raw_thresh       # sigmoid計算なしでフィルタ
ays, axs, ans = np.where(mask)    # 数百個程度に絞られる
det = out[ays, axs, ans]          # 必要な検出だけ取り出す
obj_conf = 1.0 / (1.0 + np.exp(-det[:, 4]))  # ここで初めてsigmoid

25,200 x 3 = 75,600回のsigmoid計算が、数百回に削減されます。

2. NumPyベクトル化

ループを廃止し、座標計算をNumPyの一括演算に:

cx = (sxy[:, 0] * 2 - 0.5 + axs) * stride
cy = (sxy[:, 1] * 2 - 0.5 + ays) * stride
w = (swh[:, 0] * 2) ** 2 * anchor[ans, 0]
h = (swh[:, 1] * 2) ** 2 * anchor[ans, 1]

最適化結果まとめ

最適化 後処理時間 全体FPS
Python 3重forループ 1400ms 0.6
NumPyベクトル化 270ms 2.2
+ sigmoid事前フィルタ 90ms 3.6

パフォーマンス内訳

処理 時間
カメラ取得 ~0ms(別スレッド)
前処理(resize+正規化) ~15ms
DPU推論 ~185ms
後処理(デコード+NMS) ~90ms
描画+表示 ~10ms
合計 ~275ms(3.6 FPS)

試行して効果がなかったもの

最適化 結果 理由
カメラ取得スレッド化 効果なし DPUがボトルネック
DPU推論+後処理パイプライン化 効果なし execute_asyncが実際にはブロック

VARTのexecute_asyncは名前に反して同期的に動作するようで、パイプラインによるDPUと後処理の並列実行は実現できませんでした。

実行手順

前提

  • [前回の記事]でYOLOv7のxmodelとDockerイメージ(vai-yolov7:v1)を作成済み
  • vai-yolov7:v1にOpenCV GUI(GTK)を追加してvai-yolov7:v2を作成:
sudo docker run -it vai-yolov7:v1 bash -c \
  "apt-get update && apt-get install -y libgtk2.0-dev && pip install opencv-python --force-reinstall"
sudo docker commit <container_id> vai-yolov7:v2

KV260で実行

注意: SSHではなく、KV260のHDMIモニタ前で直接操作すること。

# 1. スクリプトを配置
scp yolov7_cam.py run_yolo_cam.sh ubuntu@<KV260_IP>:~/

# 2. DPUファームウェアロード
sudo xmutil unloadapp
sudo xmutil loadapp kv260-benchmark-b4096

# 3. X11アクセス許可(KV260のデスクトップターミナルで)
export DISPLAY=:1
xhost +local:

# 4. 実行
DISPLAY=:1 bash ~/run_yolo_cam.sh

HDMIモニタにカメラ映像とバウンディングボックスが表示されます。qキーで終了。

ハマりポイント

問題 原因 解決
cv2.error: The function is not implemented opencv-python-headless(GUI無し)がインストールされていた apt install libgtk2.0-dev + pip install opencv-python --force-reinstall
could not connect to display :0 SSHセッションからX11にアクセスできない KV260のHDMIモニタ前で直接操作する
xhost: unable to open display ":0" X11ソケットが:1だった(/tmp/.X11-unix/X1 export DISPLAY=:1
DPU controller empty factory XCLBINが未ロード sudo xmutil loadapp kv260-benchmark-b4096

ソースコード

まとめ

  • KV260のDPU B4096でYOLOv7のリアルタイムカメラ検出を実現(3.6 FPS)
  • 後処理のNumPyベクトル化 + sigmoid事前フィルタで0.6FPS → 3.6FPSに改善
  • DPU推論185msが支配的で、これが現在の上限(理論上限5.4FPS)
  • パイプライン化はVARTのexecute_asyncがブロックするため効果なし
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?