
1. 开篇Jetson Nano 4GB B01 为什么还值得折腾Jetson Nano 4GB B01 的系统安装、目标检测和手势识别是我最近重新翻出来折腾的一套组合。原因很简单这块板子虽然发布有些年头了但它把 CUDA、TensorRT、OpenCV、GStreamer 和 Ubuntu 桌面塞进了一张信用卡大小的板子里价格在二手市场也不算离谱。对于想入门边缘 AI、机器视觉、机器人视觉的学生、创客和转行工程师来说它仍然是一块很好的跳板。你可以在上面跑 SSD-MobileNet 做目标检测也可以用 PoseNet 手部关键点模型加上几十行规则代码做出一个能识别石头剪刀布、点赞、数字手势的实时 Demo。整个过程会逼着你把 Linux 系统安装、供电、散热、CSI 摄像头、GStreamer 管道、TensorRT 模型部署这些环节都摸一遍。我这次的目标很明确从官方镜像烧录开始把系统装好把远程访问和 Swap 配好然后编译 jetson-inference最后分别跑通目标检测和手势识别两个官方 Demo 路线。目标检测用 detectNet手势识别用 PoseNet 的 resnet18-hand 模型。后者严格来说不是官方直接叫“手势识别”的成品 Demo而是官方姿态估计 Demo 的一个手部模型分支需要自己补一层手指伸展判断逻辑。我会把这层逻辑也写出来方便你直接复现。全文会尽量按真实操作顺序展开包括我踩过的坑、参数怎么选、性能大概什么水平、遇到问题怎么排查。适合手上已经有一块 Jetson Nano 4GB B01或者正准备入手、想先看看全流程难度的朋友。1.1 这块板子适合谁不适合谁先说适合谁。如果你是想学 TensorRT 部署、想了解边缘设备上模型推理的完整链路、想做一个小型智能摄像头或者机器人视觉节点Jetson Nano 4GB B01 非常合适。它有 128 核 Maxwell GPU、四核 ARM A57 CPU、4GB LPDDR4 内存跑轻量级目标检测和姿态估计能到十几到二十几 FPS足够做交互 Demo。它的 GPIO 兼容树莓派 40 针CSI 摄像头接口也有官方 IMX219 支持硬件生态比较成熟。再配合 JetPack 4.6.x系统里自带 CUDA 10.2、cuDNN、TensorRT、OpenCV很多环境不需要自己从零编译省掉大量时间。不适合谁如果你想在本地训练大模型、想跑 YOLOv8 大模型、想同时开多个高分辨率摄像头、想做多路视频分析Jetson Nano 4GB 会很吃力。它的内存只有 4GBCPU 性能也有限编译大项目时很容易爆内存。它的系统版本停留在 Ubuntu 18.04Python 默认是 3.6很多新库的新版本不一定兼容。所以我的建议是把它当成推理端和验证端训练放在带独显的 PC 或者云平台上。这样定位清楚之后Jetson Nano 的体验会好很多。我见过不少人一上来就想在 Nano 上训练自定义检测模型结果卡在内存和散热上最后误以为板子坏了其实只是任务选错了。1.2 这次要跑通的目标和路线这次我给自己定了三个可验收的目标。第一系统安装成功能进桌面、能联网、能 SSH系统信息里能看到 L4T 版本、CUDA、TensorRT 和 OpenCV。第二目标检测 Demo 跑通用 CSI 或 USB 摄像头实时显示检测框能识别 COCO 常见类别比如人、杯子、键盘、手机、椅子。第三手势识别 Demo 跑通先用 PoseNet 手部模型画出 21 个手部关键点再用简单几何规则判断手指伸展数量最后在画面上叠加“fist”“open”“victory”“point”这类文字。过程中我会记录分辨率、FPS、温度、电源模式这些数据方便你对照自己的环境判断是否正常。路线选择上我优先走官方 jetson-inference 项目因为它的模型下载、TensorRT 引擎生成、摄像头管道都已经封装好了适合快速验证硬件和软件栈。手势识别部分我没有直接找第三方 MediaPipe 方案因为 MediaPipe 在 Jetson Nano 的 Ubuntu 18.04 上安装依赖比较折腾而 jetson-inference 的 PoseNet 本身就带手部模型复用同一套摄像头和显示代码更省事。这个选择背后的逻辑是先用官方生态把推理链路跑通再考虑替换模型或接入自己的业务逻辑。这样出问题时排查范围小不会一上来就陷进依赖地狱。2. 系统安装前的准备电源、SD 卡、镜像与散热Jetson Nano 4GB B01 的系统安装本身不复杂但硬件准备如果马虎后面会出现各种玄学问题。我遇到最多的就是供电不足导致反复重启、SD 卡速度太慢导致系统卡死、散热不够导致跑 Demo 几分钟就降频。所以这一章先把物料和烧录讲清楚。你不需要买最贵的配件但电源、SD 卡、散热这三样不能省。尤其是 B01 版本有 DC 桶形供电口和 J48 跳线很多新手不知道要短接跳线结果插了 DC 电源仍然从 USB 口取电带不动摄像头和 GPU 满载。2.1 硬件清单与供电避坑我的建议清单如下Jetson Nano 4GB B01 开发板一块DC 5V 4A 电源一个插头规格 5.5mm x 2.1mm中心正极跳线帽一个用来短接 J48microSD 卡一张容量至少 32GB推荐 64GB速度等级 UHS-I U3、A1 或 A2USB 读卡器一个散热片加 5V 风扇一套HDMI 显示器、USB 键盘鼠标一套用于首次开机网线一根或者兼容的 USB WiFi 模块CSI 摄像头 IMX219 一个或者 USB 摄像头一个可选 USB 转 TTL 串口模块用于无显示器调试。这里每一项都有原因DC 5V 4A 是为了给 GPU 满载和摄像头留余量U3 卡是为了减少系统卡顿J48 跳线决定 DC 口是否真正供电散热片和风扇决定长时间跑 Demo 会不会降频。供电部分我要单独强调。Jetson Nano B01 的 DC 口旁边有 J48 跳线使用 DC 电源时需要用跳线帽短接。如果你用 USB-C 或者 microUSB 供电电流通常只有 5V 2A 左右跑目标检测时很容易触发欠压保护表现为突然重启、画面卡住、SSH 断开。我用 5V 2A 电源跑 detectnet 时刚开始几秒正常一旦模型加载完 GPU 拉满板子就重启。换成 5V 4A DC 电源并短接 J48 之后同样场景稳定运行。这个坑非常典型如果你遇到跑 AI Demo 就重启先检查供电不要先怀疑系统。2.2 官方镜像烧录与首次开机系统镜像我选择 NVIDIA 官方为 Jetson Nano 提供的 JetPack 4.6.x SD 卡镜像。下载下来是一个压缩包解压后得到 img 文件。烧录工具用 balenaEtcher 最省心Windows、Linux、macOS 都有版本。操作步骤是插入读卡器打开 Etcher选择镜像文件选择目标 SD 卡点击 Flash等待校验完成。注意不要选错盘否则会覆盖电脑硬盘。烧录完成后如果 Windows 提示格式化直接取消不要格式化。把 SD 卡插到 Nano 背面卡槽接好显示器、键盘鼠标、网线短接 J48插 DC 电源板子会自动开机。首次开机进入 Ubuntu 18.04 的初始设置向导。依次选择语言、键盘布局、时区然后设置用户名、密码、主机名。这里建议用户名不要用中文密码记牢因为后面 sudo 和 SSH 都要用。设置完成后系统会进行一些初始化可能黑屏几次耐心等。进入桌面后先看右上角网络图标是否联网。如果插网线一般会自动获取 IP。如果是 WiFi需要选择热点并输入密码。第一次开机后不要急着跑 Demo先确认系统信息。打开终端执行cat /etc/nv_tegra_release应该能看到 L4T 版本比如 R32.7.x。执行nvcc --version应该能看到 CUDA 10.2。执行python3 --version应该是 Python 3.6.x。这些信息正常说明基础系统没问题。2.3 首次启动后的基础检查与更新基础检查还包括 TensorRT 和 OpenCV。可以执行dpkg -l | grep tensorrt查看 TensorRT 包执行python3 -c import cv2; print(cv2.__version__)查看 OpenCV 版本。JetPack 4.6.x 一般自带 OpenCV 4.1.1。接下来可以更新系统但要有心理准备Jetson Nano 的 apt 更新可能比较慢而且升级内核相关包有风险。我的习惯是只做sudo apt update和必要的软件安装不盲目sudo apt upgrade全部包。如果你确实要升级先确保 SD 卡有足够空间电源稳定最好接显示器操作。更新完成后重启一次确认还能正常进桌面。还有一个容易被忽略的点检查磁盘空间。df -h看一下根分区剩余空间。jetson-inference 编译和模型下载会占用不少空间建议至少留 10GB 以上。如果 SD 卡是 32GB系统占掉一部分后可能比较紧张。我一般会用 64GB 卡这样编译、模型、录制的视频都有地方放。如果你打算长期用也可以考虑把系统迁移到 SSD但 Jetson Nano 的 USB 3.0 启动需要刷写 bootloader 和改配置属于进阶操作第一次玩建议先用 SD 卡跑通全流程。3. 把系统调顺远程、Swap、风扇与性能模式系统能进桌面只是第一步。要舒服地跑 Demo还需要把远程访问、Swap、风扇和性能模式配好。Jetson Nano 4GB 的内存不大编译 jetson-inference 时容易爆内存Swap 几乎是必加项。风扇如果不转跑目标检测几分钟后温度就会上去GPU 降频FPS 掉得厉害。电源模式也决定性能上限默认可能是 5W 模式需要手动切到 MAXN 10W。这些配置都不难但提前做好能省掉很多“为什么我的 FPS 这么低”的困惑。3.1 SSH 与文件传输我更习惯用 SSH 从主力电脑操作 Jetson Nano因为 Nano 桌面在 VNC 下跑 OpenGL 程序会非常卡而且 AI Demo 的显示窗口通过 VNC 看也不流畅。启用 SSH 的命令是sudo apt update sudo apt install openssh-server sudo systemctl enable ssh sudo systemctl start ssh hostname -Ihostname -I会显示 Nano 的 IP 地址。之后在主力电脑上执行ssh 用户名IP就能登录。文件传输用scp或者sftp比如把模型文件传到 Nanoscp model.onnx 用户名IP:/home/用户名/。如果你要用 VNC 做桌面配置可以在 Ubuntu 设置里打开“共享”启用屏幕共享但记住VNC 只适合改配置、看文件不适合跑实时摄像头 Demo。跑 detectnet 和 posenet 时最好直接接 HDMI 显示器或者用 SSH 看终端输出把显示输出关掉。3.2 增加 Swap防止编译爆内存Jetson Nano 4GB 的物理内存跑推理够用但编译大型项目时不够。jetson-inference 编译过程中会调用 CMake、g、Python 绑定生成等内存峰值很容易超过 4GB。我的做法是加 4GB Swap 文件。命令如下sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile free -h echo /swapfile none swap sw 0 0 | sudo tee -a /etc/fstab执行完free -h应该能看到 Swap 变成 4GB。最后一行写入/etc/fstab是为了重启后自动挂载。注意Swap 放在 SD 卡上速度比内存慢很多只能救急不能当内存用。编译时如果发现系统非常卡说明 Swap 正在频繁读写这时候可以把编译并行数降到-j1或-j2。我一般用make -j2再高就容易卡死。如果你用的是低速 SD 卡Swap 体验会更差所以前面强调 U3 卡是有道理的。3.3 风扇、时钟与电源模式散热方面如果你装了 5V 风扇可以手动控制转速。Jetson Nano 的风扇接口一般对应/sys/devices/pwm-fan/target_pwm写入 0 到 255 之间的值。开机默认可能是 0 或者较低值跑 Demo 时建议临时拉满sudo sh -c echo 255 /sys/devices/pwm-fan/target_pwm想让它自动随温度调节可以写一个简单的 systemd 服务或者脚本但第一次跑 Demo 手动拉满就够。温度监控用tegrastats可以看到 CPU、GPU、内存、温度、功耗。电源模式用sudo nvpmodel -m 0切到 MAXN 10W用sudo nvpmodel -m 1切到 5W。跑目标检测和手势识别时我建议用 MAXN。锁定最高频率用sudo jetson_clocks这会把 CPU、GPU、EMC 拉到最高频率代价是发热和功耗增加。实测在散热到位的情况下nvpmodel -m 0加jetson_clocks能让 detectnet 的 FPS 提升几帧稳定性也更好。4. 官方 Demo 环境搭建jetson-inference 编译与模型下载jetson-inference 是 NVIDIA 工程师维护的推理示例集合包含图像分类、目标检测、语义分割、姿态估计等。它把 TensorRT 推理、摄像头输入、OpenGL 显示封装成了 C 和 Python API适合快速验证。编译这个项目是本次系统安装后最关键的一步也是最容易出问题的一步。只要这一步过了后面的 detectnet 和 posenet 基本都是命令参数调整。我建议在编译前先确认 Swap 已经启用电源稳定SD 卡剩余空间足够。4.1 源码获取与依赖安装先安装基础依赖sudo apt-get install git cmake libpython3-dev python3-numpy然后克隆源码注意要加--recursive因为子模块里有 TensorRT 工具和模型下载脚本git clone --recursive https://github.com/dusty-nv/jetson-inference cd jetson-inference如果你的网络下载 GitHub 比较慢可以提前在别的机器上下载 zip 包再用 scp 传到 Nano。不要用不可靠的第三方修改版避免引入后门或兼容问题。克隆完成后可以看一下目录结构tools目录下有模型下载脚本python目录下有 Python 示例c目录下有 C 示例。接下来创建 build 目录并配置 CMakemkdir build cd build cmake ../CMake 过程中可能会提示是否下载 PyTorch 等组件按默认选择即可。如果提示下载模型也可以先跳过后面单独下载。注意看终端输出如果有依赖缺失按提示安装。常见缺失包括libpython3-dev、python3-numpy、git、cmake。安装完重新执行 CMake。4.2 编译参数与内存控制配置完成后开始编译make -j2 sudo make install sudo ldconfigmake -j2表示用两个并行任务。Jetson Nano 四核 CPU理论上可以-j4但 4GB 内存很容易被撑爆。我用-j2比较稳编译时间大概几十分钟到一两个小时取决于 SD 卡速度和散热。如果中途报错virtual memory exhausted或者进程被 killed说明内存不够降到-j1再试。编译成功后执行sudo make install把库和可执行文件安装到系统目录。sudo ldconfig刷新动态库缓存。之后可以进入build/aarch64/bin目录看到detectnet-camera、posenet-camera、imagenet-camera等可执行文件。编译过程中如果风扇没转建议手动拉满并且用tegrastats观察温度。温度长期超过 80 摄氏度GPU 会降频编译时间会变长。如果编译到一半断电可能留下不完整的 build 目录最好删掉build重新来。我的经验是编译前先free -h确认 Swap 生效编译时不要开桌面浏览器和视频播放器尽量用 SSH 操作减少桌面占用。这样一次成功的概率高很多。4.3 模型下载与 TensorRT 引擎生成编译完成后下载预训练模型cd ~/jetson-inference/tools ./download-models.sh脚本会列出可下载的模型包括图像分类、目标检测、语义分割、姿态估计。目标检测我选ssd-mobilenet-v2手势识别我选resnet18-hand。你可以用空格键选择回车确认。模型会下载到jetson-inference/data/networks目录。下载完成后第一次运行 Demo 时TensorRT 会把 ONNX 或 Caffe 模型转换成.engine文件。这个过程可能需要几分钟终端会显示进度。转换完成后后续启动会直接加载 engine速度快很多。这里有一个重要细节TensorRT engine 和具体的 TensorRT 版本、GPU 架构绑定。如果你换了 JetPack 版本或者把 engine 拷到别的设备可能无法使用需要重新生成。所以不要把 engine 当成通用模型文件。模型下载如果中断可以重新运行脚本它会跳过已完成的文件。如果你手动下载模型注意目录结构要和脚本预期一致否则运行时找不到。下载完可以用ls -lh data/networks查看模型大小确认文件完整。5. 目标检测官方 Demo 实测目标检测是 Jetson Nano 最经典的 Demo 之一。jetson-inference 提供的 detectNet 支持 SSD-MobileNet-v2、SSD-Inception-v2 等模型在 COCO 数据集上训练可以识别 80 类常见物体。实测下来SSD-MobileNet-v2 在 640x480 分辨率下能到 20 FPS 左右具体取决于电源模式、散热、摄像头和背景复杂度。这个性能做交互 Demo 够用但不要期望像桌面显卡那样流畅。目标检测跑通之后你可以很直观地看到模型输入、推理、后处理、叠加框、显示整个链路。5.1 摄像头选择与 GStreamer 管道Jetson Nano 支持 CSI 摄像头和 USB 摄像头。CSI 摄像头通过 MIPI CSI-2 接口连接延迟低CPU 占用少官方 IMX219 驱动支持好。USB 摄像头即插即用但会占用 USB 带宽和 CPU。我的建议是优先用 CSI 摄像头。连接 CSI 摄像头时注意排线方向金属触点朝向散热片方向排线插到底卡扣压紧。接好后执行ls /dev/video*应该能看到/dev/video0。如果看不到检查排线和驱动。USB 摄像头一般也是/dev/video0或/dev/video1可以用v4l2-ctl --list-devices查看。jetson-inference 内部用 GStreamer 抓取摄像头。CSI 摄像头的管道通常是nvarguscamerasrcUSB 摄像头是v4l2src。如果你直接用默认参数运行 Demo程序会自动选择。但为了稳定我建议手动指定分辨率。比如 CSI 摄像头可以用./detectnet-camera --camera/dev/video0 --width640 --height480 --networkssd-mobilenet-v2如果报错找不到摄像头可以尝试指定csi://0或v4l2:///dev/video0。GStreamer 报错信息通常比较长重点看最后几行常见原因是摄像头被其他进程占用、排线接触不良、分辨率不支持。跑之前可以用nvgstcapture-1.0测试 CSI 摄像头用cheese或fswebcam测试 USB 摄像头。5.2 detectnet-camera 运行与参数进入可执行文件目录cd ~/jetson-inference/build/aarch64/bin ./detectnet-camera /dev/video0 --networkssd-mobilenet-v2 --width640 --height480 --threshold0.5第一次运行会生成 TensorRT engine等待几分钟。看到视频窗口后画面中的人、杯子、键盘等物体会被框出来并显示类别和置信度。--threshold0.5表示只显示置信度大于 0.5 的检测框调低会显示更多框但误检也更多。--overlaybox,labels,conf可以控制叠加内容。如果你想保存检测结果可以用--output-codech264和--output/path/output.mp4但会占用额外 CPU。Python 版本命令类似python3 detectnet-camera.py --networkssd-mobilenet-v2 --width640 --height480实测中SSD-MobileNet-v2 在 640x480 下比较流畅人物、椅子、瓶子、手机识别率不错。小物体、遮挡物体、逆光场景容易漏检。置信度阈值不要设太低否则背景纹理也可能被误认为目标。如果你的应用需要检测特定类别可以用--filter参数只显示某些类别比如--filterperson,cup这样画面更干净后处理也更容易。5.3 性能记录与优化我在 MAXN 10W 模式、jetson_clocks开启、风扇 255 的条件下做了几组记录。SSD-MobileNet-v2 在 640x480 下大约 18 到 24 FPS1280x720 下降到 10 到 14 FPS。SSD-Inception-v2 精度略高但速度明显慢一些640x480 大约 10 到 14 FPS。温度方面不加散热片只靠被动散热几分钟后温度超过 80 度FPS 会掉到个位数。加了散热片和风扇后温度稳定在 55 到 65 度FPS 波动小很多。功耗方面MAXN 模式下整板峰值可以到 10W 左右5V 4A 电源完全够用。优化技巧有几个。第一降低输入分辨率到 640x480对 FPS 提升最明显。第二使用 SSD-MobileNet-v2 而不是 Inception 系列。第三锁定 MAXN 和 jetson_clocks。第四关闭桌面动画和浏览器减少 CPU 占用。第五如果不需要实时显示可以用--headless模式只保存结果FPS 会更高。第六确保 TensorRT 使用 FP16jetson-inference 默认会尝试 FP16如果模型不支持会回退 FP32。第七摄像头帧率不要设太高30fps 足够设 60fps 反而增加 USB 带宽和 CPU 负担。实测这些调整叠加后SSD-MobileNet-v2 可以稳定在 20 FPS 以上。6. 手势识别 Demo 实测手势识别部分我走的是 PoseNet 手部模型路线。jetson-inference 的 PoseNet 支持人体姿态和手部姿态resnet18-hand模型可以输出 21 个手部关键点。官方 Demo 运行后会在手上画出骨架但它不会直接告诉你这是“石头”还是“布”。所以我加了一层几何规则计算每根手指的指尖到手腕距离和对应指节到手腕距离比较判断手指是否伸直。这个方法简单、可解释、不需要训练适合快速做出交互 Demo。当然它对遮挡和光照比较敏感后面也可以换成训练分类器。6.1 PoseNet 手部模型跑通先运行官方 PoseNet 手部 Democd ~/jetson-inference/build/aarch64/bin ./posenet-camera /dev/video0 --networkresnet18-hand --width640 --height480 --threshold0.5第一次运行会生成 TensorRT engine等待几分钟。之后视频窗口会显示手部关键点骨架。实测在 640x480 下resnet18-hand 大约 12 到 18 FPS比 SSD-MobileNet-v2 稍慢但足以做手势交互。手部离摄像头太远、光线太暗、背景杂乱时关键点会抖动或丢失。建议手部占据画面较大比例背景简单光线均匀。如果画面中没有手模型不会输出姿态程序也不会报错。Python 版本命令类似python3 posenet-camera.py --networkresnet18-hand --width640 --height480注意PoseNet 的手部模型输出的是关键点坐标不是手势类别。你要先确认关键点稳定再做分类。如果关键点本身跳动很厉害分类结果也会不稳定。我的做法是在关键点上加一个简单的滑动平均滤波比如保存最近 5 帧的坐标取平均后再判断手指伸展。这样手势文字不会频繁闪烁。6.2 手部关键点索引与规则分类手部 21 个关键点的常见索引是0 手腕1 到 4 拇指5 到 8 食指9 到 12 中指13 到 16 无名指17 到 20 小指。每根手指的 4 个点从根部到指尖排列。判断手指伸直的一个简单规则是指尖到手腕的距离大于第二指节到手腕的距离乘以一个阈值。比如食指指尖是 8第二指节是 6如果dist(8,0) dist(6,0) * 1.15就认为食指伸直。拇指因为结构不同可以用指尖 4 和指节 3 到手腕的距离比较或者结合拇指和食指根部的距离。阈值 1.15 是我实测下来比较稳的经验值你也可以根据手的大小调整。根据伸直手指数量可以粗略分类0 根伸直是握拳1 根是点赞或指方向2 根是剪刀手5 根是张开手掌3 根或 4 根可以定义为数字手势。实际测试中拇指判断最容易出错因为拇指活动范围大关键点容易和掌心重叠。我的建议是先把食指、中指、无名指、小指四根判断准拇指单独处理或者先忽略。对于石头剪刀布你只需要判断 0 根、2 根、5 根三种状态稳定性会好很多。先把简单场景做稳再扩展复杂手势。6.3 一个可运行的手势识别脚本下面这段代码是在 jetson-inference Python API 基础上改的核心逻辑是读取 PoseNet 关键点判断手指伸展然后在画面上叠加手势文字。你可以在jetson-inference/build/aarch64/bin目录下新建gesture.py根据你的摄像头类型调整输入源。import jetson.inference import jetson.utils net jetson.inference.poseNet(resnet18-hand, threshold0.5) camera jetson.utils.videoSource(csi://0, argv[--input-width640, --input-height480, --input-rate30]) display jetson.utils.videoOutput(display://0) finger_tips [4, 8, 12, 16, 20] finger_pips [3, 6, 10, 14, 18] hand_pairs [ (0,1),(1,2),(2,3),(3,4), (0,5),(5,6),(6,7),(7,8), (0,9),(9,10),(10,11),(11,12), (0,13),(13,14),(14,15),(15,16), (0,17),(17,18),(18,19),(19,20) ] def dist(a, b): return ((a.x - b.x) ** 2 (a.y - b.y) ** 2) ** 0.5 while display.IsStreaming(): img camera.Capture() poses net.Process(img) gesture none for pose in poses: kps {kp.ID: kp for kp in pose.Keypoints} if all(i in kps for i in finger_tips [0]): extended 0 for tip, pip in zip(finger_tips, finger_pips): if dist(kps[tip], kps[0]) dist(kps[pip], kps[0]) * 1.15: extended 1 if extended 0: gesture fist elif extended 5: gesture open elif extended 2: gesture victory elif extended 1: gesture point else: gesture {} fingers.format(extended) for a, b in hand_pairs: if a in kps and b in kps: jetson.utils.cudaDrawLine( img, (kps[a].x, kps[a].y), (kps[b].x, kps[b].y), (0, 255, 0, 200), 2) for kp in pose.Keypoints: jetson.utils.cudaDrawCircle(img, (kp.x, kp.y), 3, (255, 0, 0, 200)) if gesture ! none: jetson.utils.cudaDrawText( img, (10, 10), Gesture: gesture, (255, 255, 0, 255), 24) display.Render(img) display.SetStatus(Hand Gesture | FPS {:.1f}.format(net.GetNetworkFPS()))运行命令是python3 gesture.py。如果使用 USB 摄像头把csi://0改成/dev/video0。如果显示窗口打不开确认你是本地 HDMI 显示而不是 VNC。实测这个脚本在 640x480 下能稳定识别张开手掌、握拳、剪刀手。手势文字偶尔会跳变可以加一个队列连续 3 帧同一结果才更新显示。另外cudaDrawText的字体大小和位置可以根据画面调整别让文字挡住手部关键点。6.4 训练自己的手势分类器思路规则分类适合快速验证但如果你要识别复杂手势比如数字 1 到 10、特定手势指令最好训练一个分类器。思路是先用 jetson-inference 的camera-capture工具采集手势图片每个类别拍几百张注意变换背景、光照、手部角度。然后在 PC 上用 PyTorch 训练一个轻量级分类网络比如 MobileNetV2 或 ResNet18输入 224x224 图片输出手势类别。训练完成后导出 ONNX再在 Jetson Nano 上用 TensorRT 加载。这样推理速度可以做到实时而且比规则分类更鲁棒。不要在 Jetson Nano 本地训练大模型它的 CPU 和内存不适合训练放在 PC 上更实际。如果你不想自己搭训练流程也可以考虑 Edge Impulse 这类边缘 AI 平台采集数据、训练、导出 TensorRT 或 TFLite 模型流程比较完整。不过要注意模型输入输出和 jetson-inference 的封装不同可能需要自己写后处理。我的建议是先用规则版跑通交互再根据实际需求决定是否训练。很多场景下五指伸展规则加手势轨迹判断已经够用。训练分类器的价值在于处理复杂手势和不同用户的手型差异但工作量也更大。7. 常见问题与排查速查表Jetson Nano 的坑大多集中在几个地方供电、SD 卡、摄像头、编译内存、TensorRT 模型。下面是我整理的问题速查表按现象、可能原因、解决方法组织。你可以先查表再针对性看日志。排查时尽量一次只改一个变量否则很难定位。比如摄像头不工作先换官方 CSI 摄像头测试再换 USB 摄像头再检查 GStreamer 管道不要同时改分辨率、摄像头类型和电源模式。7.1 启动与供电类问题现象可能原因解决方法插电后绿灯亮但无显示HDMI 线或显示器不兼容、SD 卡未插好换 HDMI 线、换显示器、重新插卡开机反复重启电源电流不足、J48 未短接换 5V 4A DC 电源短接 J48系统卡在启动 LogoSD 卡速度慢或镜像写坏换 U3 卡重新烧录并校验跑 Demo 几分钟后重启GPU 满载导致欠压检查电源、散热、Swap降低分辨率SSH 突然断开网络不稳或供电不足插网线检查电源查看温度供电问题我遇到最多。尤其是用 USB 口供电时目标检测一跑起来电流瞬间拉高板子直接重启。不要用手机充电器凑合最好用官方推荐的 DC 5V 4A 电源。J48 跳线也要确认短接。如果你不知道跳线帽怎么插可以看板子 DC 口旁边的丝印通常标着 J48短接两个针脚即可。7.2 摄像头与显示类问题现象可能原因解决方法找不到 /dev/video0CSI 排线接反或未插紧关机重插排线金属触点朝向散热片CSI 摄像头画面全黑分辨率或帧率不支持用 nvgstcapture 测试改 1280x720USB 摄像头卡顿USB 带宽不足或 CPU 占用高换 USB 3.0 口降低分辨率GStreamer 报错管道参数错误或摄像头被占用关闭其他摄像头进程检查管道VNC 下无法显示 AI 窗口OpenGL 远程渲染受限接 HDMI 本地显示SSH 看日志显示方面jetson-inference 的窗口使用 OpenGL。VNC 虽然能看到桌面但跑实时视频窗口体验很差。我的建议是配置阶段用 SSH跑 Demo 时接 HDMI 显示器。如果必须无头运行可以用--headless参数把结果保存成视频文件再传到电脑看。CSI 摄像头的排线很脆弱插拔时先关机不要带电操作。7.3 编译与模型类问题现象可能原因解决方法make 报内存不足4GB 内存不够加 4GB Swap用 make -j1CMake 找不到 Python缺少 libpython3-dev安装依赖重新 cmake模型下载中断网络不稳或磁盘满重新运行下载脚本清理空间TensorRT engine 生成失败模型文件损坏或版本不匹配删除 engine 重新生成检查 JetPack 版本Python 导入 jetson.inference 失败未 make install 或 ldconfig执行 sudo make install 和 sudo ldconfig编译类问题里内存不足最常见。症状是终端突然显示Killed或者编译进程消失。加 Swap 并降低并行数基本能解决。模型下载和 TensorRT 引擎生成需要耐心第一次可能比较慢。如果 engine 生成失败先看终端输出的错误常见是模型文件不完整。删除data/networks下对应的 engine 文件重新运行 Demo 让它再生成一次。7.4 性能与稳定性类问题现象可能原因解决方法FPS 很低5W 模式、未锁频、分辨率高nvpmodel -m 0jetson_clocks降到 640x480温度过高降频散热不足加散热片和风扇风扇 PWM 拉满画面延迟大摄像头管道缓冲多降低分辨率减少缓冲用 CSI 摄像头手势识别抖动关键点不稳定滑动平均滤波连续多帧确认检测框闪烁阈值太低或模型误检提高阈值使用 filter 过滤类别性能优化没有银弹就是分辨率、模型、电源模式、散热四个变量一起调。我的经验是640x480 是 Jetson Nano 的甜点分辨率再高 FPS 掉得厉害。SSD-MobileNet-v2 和 resnet18-hand 都是轻量模型适合 Nano。散热一定要做好温度一高什么优化都白搭。如果你发现 FPS 突然从 20 掉到 5先看温度再看电源模式最后看是否有其他进程占用 CPU。8. 最后聊几句实际体会我在 Jetson Nano 4GB B01 上反复装过几次系统最大的体会是这块板子的性能瓶颈往往不在 GPU而在供电、散热和存储。同样的 detectnet 代码用 5V 2A 电源跑几分钟就重启换 5V 4A DC 电源加风扇后稳定运行同样的 SD 卡U1 卡编译时卡到怀疑人生U3 卡顺畅很多。所以如果你刚开始玩不要急着换模型、改代码先把硬件基础打好。系统安装、Swap、风扇、电源模式这几步做扎实后面的目标检测和手势识别会顺很多。手势识别部分PoseNet 手部模型给了我很大惊喜21 个关键点足够做很多交互。虽然它有抖动和遮挡问题但加一个滑动平均和连续帧确认体验就能接受。如果你的项目需要更稳定的手势分类再考虑采集数据训练轻量分类器。目标检测部分SSD-MobileNet-v2 在 Nano 上性价比很高20 FPS 左右足够做智能监控、物体计数、简单机器人视觉。后续你还可以把检测结果通过串口或 GPIO 发给单片机做联动控制。这个扩展方向比单纯在屏幕上画框更有意思也更能体现边缘计算的价值。