购买即可解锁1000+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,每日更新

Jetson Nano + YOLO26 + TensorRT:边缘 AI 实时目标检测

一、部署链路

PC (训练 + 导出 engine)            Jetson Nano (推理)
─────────────────────              ─────────────────
YOLO26.pt (PyTorch)
      ↓ yolo export
YOLO26.onnx
      ↓ trtexec (PC 端)
YOLO26.engine (FP16)  ─── scp ───→  TensorRT C++/Python
                                         ↓
                                    CSI / USB 摄像头 → 推理 → HDMI 显示

Jetson Nano 拥有 128 核 Maxwell GPU,FP16 算力约 0.5 TOPS。跑 YOLO26n(320 输入)可达 30 FPS 左右。

二、Jetson Nano 系统准备

2.1 烧录系统

使用 NVIDIA SDK Manager 烧录 JetPack 4.6(Ubuntu 18.04 + CUDA 10.2 + TensorRT 8.2)。

2.2 初始配置

# 设置 MAXN 性能模式
sudo nvpmodel -m 0
sudo jetson_clocks

# 换源(ARM64 架构,用清华源)
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's/ports.ubuntu.com/mirrors.tuna.tsinghua.edu.cn\/ubuntu-ports/g' /etc/apt/sources.list

sudo apt update && sudo apt upgrade -y

# 安装基础依赖
sudo apt install python3-pip libopencv-dev -y

2.3 安装 PyTorch(Jetson 预编译版)

Jetson 上的 PyTorch 需要从 NVIDIA 官方预编译包安装:

# JetPack 4.6 对应 Python 3.6
wget https://developer.download.nvidia.com/compute/redist/jp/v46/pytorch/torch-1.12.0a0+...cp36-cp36m-linux_aarch64.whl
pip3 install torch-1.12.0*.whl

# 验证
python3 -c "import torch; print(torch.__version__)"

三、PC 端:模型导出为 TensorRT Engine

在 PC(X86 + NVIDIA GPU)上操作。导出的 engine 文件可直接复制到 Jetson Nano——只要 Jetson 与 PC 的 TensorRT 版本一致或兼容。

3.1 导出 ONNX

pip install ultralytics

# 导出为 ONNX(opset=11,Jetson 兼容性好)
yolo export model=yolo26n.pt format=onnx simplify=True opset=11

3.2 安装 TensorRT(PC 端)

从 NVIDIA 官网下载 TensorRT 8.2 对应 CUDA 10.2 的版本,或者用 pip:

pip install tensorrt

3.3 ONNX → TensorRT Engine

# FP16(推荐,几乎无精度损失)
trtexec --onnx=yolo26n.onnx \
        --saveEngine=yolo26n_fp16.engine \
        --fp16 \
        --workspace=2048 \
        --minShapes=images:1x3x320x320 \
        --optShapes=images:1x3x320x320 \
        --maxShapes=images:1x3x320x320

如果后续要切换到 640 输入,把 320 改成 640 重新生成即可。

3.4 复制到 Jetson

scp yolo26n_fp16.engine jetson@jetson-ip:/home/jetson/

四、Jetson 端:TensorRT Python 推理

import cv2
import numpy as np
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit

TRT_LOGGER = trt.Logger(trt.Logger.WARNING)


class TRTYOLO:
    def __init__(self, engine_path):
        with open(engine_path, "rb") as f:
            runtime = trt.Runtime(TRT_LOGGER)
            self.engine = runtime.deserialize_cuda_engine(f.read())
        self.context = self.engine.create_execution_context()
        self.stream = cuda.Stream()

        self.inputs, self.outputs, self.bindings = [], [], []
        for binding in self.engine:
            size = trt.volume(self.engine.get_binding_shape(binding))
            dtype = trt.nptype(self.engine.get_binding_dtype(binding))
            host = cuda.pagelocked_empty(size, dtype)
            device = cuda.mem_alloc(host.nbytes)
            self.bindings.append(int(device))
            if self.engine.binding_is_input(binding):
                self.inputs.append({"host": host, "device": device, "shape": self.engine.get_binding_shape(binding)})
            else:
                self.outputs.append({"host": host, "device": device})

    def infer(self, img):
        h, w = img.shape[:2]
        inp_h, inp_w = self.inputs[0]["shape"][2:]
        scale = min(inp_h / h, inp_w / w)
        nh, nw = int(h * scale), int(w * scale)
        resized = cv2.resize(img, (nw, nh))
        canvas = np.full((inp_h, inp_w, 3), 114, dtype=np.uint8)
        dh = (inp_h - nh) // 2
        dw = (inp_w - nw) // 2
        canvas[dh:dh+nh, dw:dw+nw] = resized

        inp = canvas.astype(np.float32) / 255.0
        inp = inp.transpose(2, 0, 1).ravel()
        np.copyto(self.inputs[0]["host"], inp)

        cuda.memcpy_htod_async(self.inputs[0]["device"], self.inputs[0]["host"], self.stream)
        self.context.execute_async_v2(self.bindings, self.stream.handle)
        cuda.memcpy_dtoh_async(self.outputs[0]["host"], self.outputs[0]["device"], self.stream)
        self.stream.synchronize()

        return self.outputs[0]["host"], scale, dh, dw

    def postprocess(self, output, scale, dh, dw, conf_thr=0.3):
        dets = output.reshape(1, 84, 8400)[0]
        boxes, scores, cls_ids = [], [], []
        for i in range(dets.shape[1]):
            max_score = dets[4:, i].max()
            if max_score < conf_thr:
                continue
            cls_id = int(dets[4:, i].argmax())
            cx, cy, bw, bh = dets[:4, i]
            x1 = (cx - bw/2 - dw) / scale
            y1 = (cy - bh/2 - dh) / scale
            x2 = (cx + bw/2 - dw) / scale
            y2 = (cy + bh/2 - dh) / scale
            boxes.append([x1, y1, x2, y2])
            scores.append(float(max_score))
            cls_ids.append(cls_id)
        return np.array(boxes), np.array(scores), cls_ids if boxes else ([], [], [])


def main():
    model = TRTYOLO("yolo26n_fp16.engine")

    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

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

        output, scale, dh, dw = model.infer(frame)
        boxes, scores, cls_ids = model.postprocess(output, scale, dh, dw)

        for box, score in zip(boxes, scores):
            x1, y1, x2, y2 = box.astype(int)
            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.putText(frame, f"{score:.2f}", (x1, y1 - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)

        cv2.imshow("Jetson Nano YOLO26", frame)
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break

    cap.release()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

五、性能

芯片 模型 输入 精度 延迟 FPS
Jetson Nano YOLO26n 320 FP16 ~30ms ~30
Jetson Nano YOLO26n 640 FP16 ~70ms ~14
Jetson Orin Nano 8GB YOLO26n 640 FP16 ~12ms ~80
Jetson Orin Nano 8GB YOLO26s 640 FP16 ~25ms ~40

Nano 上 320 输入 + FP16 是实时运行的最佳平衡点。640 输入可以跑但 FPS 较低。

六、常见问题

问题 原因 解决
trtexec 报错 “Unsupported layer” ONNX opset 太高 用 opset=11 重新导出
Python 推理段显存不足 pycuda 未释放资源 cuda.Context.pop() 或 C++ 实现
摄像头打不开 设备号不对或权限不足 ls /dev/video*sudo chmod 666 /dev/video0
推理结果全为 0 engine 输入 shape 与代码不匹配 确认 preprocess 的输入尺寸与 engine 一致
import pycuda 报错 未安装或版本对不上 pip3 install pycuda

七、自定义模型

在 PC 上训练:

yolo train model=yolo26n.pt data=custom.yaml epochs=100
yolo export model=runs/detect/train/weights/best.pt format=engine half=True
scp best.engine jetson@jetson-ip:/home/jetson/

Jetson 端直接用 TRTYOLO("best.engine") 加载。

八、扩展

应用 模型 备注
人脸检测 YOLO26n-face 微调的人脸检测专用版本
口罩检测 YOLO26n-mask 口罩数据集微调
车牌检测 YOLO26n-license 车牌检测 + 识别
行人检测 YOLO26n-pedestrian 可过滤非行人类别只用 person

九、总结

Jetson Nano 上跑 YOLO26 需要 TensorRT 加速才能达到实时。推荐输入 320×320 + FP16 精度,延迟约 30ms,可覆盖大部分实时检测场景。部署流程是 PC 端训练 → yolo export format=engine half=True → scp 到 Jetson → TensorRT Python/C++ 推理。先在 PC 上用 trtexec 验证 engine 可正常推理后,再部署到 Nano,可以省去 Jetson 上编译 engine 的时间。

代码链接与详细流程

飞书链接:https://ecn6838atsup.feishu.cn/wiki/EhRtwBe1CiqlSEkHGUwc5AP9nQe?from=from_copylink
密码:946m22&8
链接可用,不要多复制空格了

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐