Jetson Nano + YOLO26 + TensorRT:边缘 AI 实时目标检测
文章目录
购买即可解锁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
链接可用,不要多复制空格了
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)