
Jetson NanoでYOLOのリアルタイム検出をやろうとすると、次の壁に当たりがちです。
- Jetson本体のUbuntu(ホスト)にPythonスクリプトを置いたけど、ホストのPython環境では動かない
- YOLO/TensorRTが動くのはDocker内なのに、どうやってPythonを編集しながら実行するの?
cv2.imshow()が出ない(GUIがない)問題で止まる
この記事では、Jetson上でコマンド1発で起動して、映像(bbox付き)を表示しながらPythonを修正→再実行できる開発ループを作ります。
ゴールはこれです:
~/yolo_dev/run.shを叩くだけで起動できる- Jetsonホスト上の
~/yolo_devにPythonコードを置く - 実行はDocker内Pythonで行う(YOLO/TensorRT環境をそのまま利用)
- USBカメラの映像にbboxを描画して、Jetsonの画面にリアルタイム表示できる
環境構築の記事と、yolo特有のコマンドだけで動かすリアルタイム処理の実行の記事は以下を参照してください。
前提(重要):なぜ「Jetsonホストでpython実行」じゃなく「Docker内python実行」なのか
Jetson NanoはJetPackの制約が強く、PyTorch/TensorRT/OpenCVなどの組み合わせが崩れやすいです。
そのため「動く環境」をDockerに閉じ込めるのが現実的です。
ただし、Pythonを開発するには毎回Dockerに入って編集するのは面倒。
そこで、
- コードはホストに置く
- Dockerからそのフォルダをマウントして実行する
という形にします。これが一番ストレスがありません。
全体像(開発ループ)
- Jetsonホストで
~/yolo_devにコードを置く run.shでdocker run ... python3 cam_predict_opencv.pyを起動- Jetsonの画面にリアルタイム表示される
- コード修正 →
run.sh再実行
1. 作業フォルダを作る(ホスト側)
mkdir -p ~/yolo_dev
mkdir -p ~/yolo_out
2. TensorRT engine(.engine)を作業フォルダへ置く(ホスト側)
今回は手元にある yolo11n.engine を使います(すでに作成済みの前提)。
cp /home/ai/jetson_yolo_artifacts/yolo11n.engine ~/yolo_dev/yolo11n.engine
ls -lh ~/yolo_dev/yolo11n.engine
ポイント:Dockerから見える場所(マウントする場所)にモデルファイルを置くこと。
ホストにファイルがあっても、Dockerにマウントしない限りDockerからは見えません。
3. リアルタイム表示するPython(OpenCV+Ultralytics)を作る
~/yolo_dev/cam_predict_opencv.py を作ります。
(nano がない環境でもOKなように cat で作成します)
cat > ~/yolo_dev/cam_predict_opencv.py <<'EOF'
import os
import time
import cv2
import numpy as np
# TensorRTがnp.bool参照で落ちる環境の回避
if not hasattr(np, "bool"):
np.bool = bool
from ultralytics import YOLO
def open_cam(dev="/dev/video0", w=640, h=480, fps=30):
cap = cv2.VideoCapture(dev, cv2.CAP_V4L2)
if not cap.isOpened():
raise RuntimeError(f"Camera open failed: {dev}")
cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
cap.set(cv2.CAP_PROP_FPS, fps)
return cap
def main():
model_path = os.getenv("MODEL", "yolo11n.engine")
imgsz = int(os.getenv("IMGSZ", "320"))
conf = float(os.getenv("CONF", "0.25"))
show = (os.getenv("SHOW", "1") == "1") # デフォルト表示ON
model = YOLO(model_path)
cap = open_cam()
t0 = time.time()
frames = 0
try:
while True:
ok, frame = cap.read()
if not ok:
continue
results = model.predict(
source=frame,
imgsz=imgsz,
conf=conf,
device=0,
half=True,
verbose=False,
)
annotated = results[0].plot()
if show:
cv2.imshow("YOLO Live (press q to quit)", annotated)
if cv2.waitKey(1) & 0xFF == ord("q"):
break
frames += 1
if frames % 30 == 0:
dt = time.time() - t0
print(f"FPS ~ {frames/dt:.2f}")
except KeyboardInterrupt:
print("Interrupted (Ctrl+C)")
finally:
cap.release()
if show:
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
EOF
このコードのポイント
model = YOLO("yolo11n.engine")で TensorRT engine を使う(速い)cv2.imshow()で bbox付き映像をリアルタイム表示np.bool問題(TensorRT×NumPyの相性)を回避
4. Jetsonでコマンド1発起動できる run.sh を作る(重要)
毎回長い docker run ... を打ちたくないので、起動用のシェルを作ります。
これがあると開発体験が一気に良くなります。
cat > ~/yolo_dev/run.sh <<'EOF'
#!/usr/bin/env bash
set -e
# Jetson本体の画面に出す(モニタ直結想定)
export DISPLAY=:0
xhost +local:root >/dev/null 2>&1 || true
sudo docker run -it --rm \
--runtime nvidia \
--network host \
--device /dev/video0:/dev/video0 \
-e DISPLAY=:0 \
-e SHOW=1 \
-v /tmp/.X11-unix:/tmp/.X11-unix \
-v "$HOME/yolo_dev:/work" -w /work \
ultralytics/ultralytics:jetpack4-gui \
env MODEL=yolo11n.engine IMGSZ=320 CONF=0.25 \
python3 cam_predict_opencv.py
EOF
chmod +x ~/yolo_dev/run.sh
ultralytics/ultralytics:jetpack4-guiは GUI対応のOpenCV入りイメージです。
もしあなたの環境でタグ名が違う場合は、ここだけ置き換えてください。
5. 起動する(ホスト側でこれだけ)
~/yolo_dev/run.sh
- Jetsonの画面に bbox付きの映像が表示されます
- 終了は
qまたはCtrl+C
6. 開発のやり方(Pythonをいじってすぐ試す)
開発ループはこれだけです。
~/yolo_dev/cam_predict_opencv.pyを修正~/yolo_dev/run.shを実行- 表示を見ながら調整
- また修正 → 実行
Docker内に入って編集する必要はありません。
ホストで編集 → Dockerで実行が最強です。
よくある詰まりポイント
1) FileNotFoundError: 'xxx.engine' does not exist
モデルファイルが /work(= ~/yolo_dev)に無いと起きます。
→ engineを ~/yolo_dev に置く(マウント対象に置く)が正解。
2) cv2.imshow() が出ない / destroyAllWindows() で落ちる
OpenCVがGUI無し(headless)だと起きます。
→ GUI対応イメージ(jetpack4-gui) を使うのが正解。
3) np.bool エラーで落ちる(TensorRT絡み)
環境によって tensorrt が np.bool を参照して落ちます。
→ スクリプト先頭の回避コード(np.bool = bool)で通ることが多いです。
YOLO12にするには?
この記事は動作確認済みの yolo11n.engine で説明しました。
YOLO12にしたい場合は、
yolo12n.engineを用意して~/yolo_devに置くrun.shのMODEL=yolo11n.engineをMODEL=yolo12n.engineに変える
これだけです。Python側はそのまま使えます。
まとめ
run.sh 化すれば、開発が爆速になる
- コードはホストに置く
- 実行はDocker内で行う
- X11を渡してJetson画面にリアルタイム表示する
run.sh化すれば、開発が爆速になる
TensorRTで動かす一連の流れは次の記事で紹介します。
それではまた。






LEAVE A REPLY