ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

NVIDIA Jetson TX2 跑通 OpenPose 人体关键点检测完整实战指南

NVIDIA Jetson TX2 跑通 OpenPose 人体关键点检测完整实战指南 就在几个月前我把一块落灰已久的 NVIDIA Jetson TX2 翻了出来打算让它跑起经典的 OpenPose 人体关键点检测。说实话上手前我心里也没底TX2 在今天的嵌入式板卡里算是“老将”了而 OpenPose 无论是早期基于 Caffe 的版本还是后来 PyTorch 的重写版对显存和算力的要求都不低。网上关于“在 TX2 上跑 OpenPose”的教程大多零零散散有说能跑实时也有说卡成 PPT实际操作时会遇到什么坑只有自己踩一遍才知道。这篇文章我会完整复盘一遍在 Jetson TX2 上从零开始跑通 OpenPose 的全过程包括环境版本怎么选、Caffe 分支怎么编、模型去哪下、参数怎么调以及我自己遇到的和网上高频出现的各种报错。不管你是想在边缘设备上做姿态估计的工程师还是刚入手 TX2 想折腾深度学习部署的学生这篇文章应该都能帮你省下不少时间。1. 项目概述与环境背景1.1 OpenPose 到底是什么为什么选它OpenPose 是一个开源的人体姿态估计项目核心能力是同时检测画面里多个人体的关键点比如肩膀、手肘、手腕、膝盖、脚踝甚至还能做手部关键点和面部关键点检测。它输出的结果是一组坐标和置信度可以直接喂给上层应用做动作识别、健身计数、人机交互等。选择 OpenPose 的原因很直接它提出的 PAFPart Affinity Fields部位亲和场方法在 2017 年前后是学术界和工业界公认的标杆而且提供了非常完整的 C/Python 接口和预训练模型。虽然现在有更轻量的 MoveNet、MediaPipe 等方案但 OpenPose 的算法思路和部署方式依然是理解姿态估计任务的很好入口。尤其在 TX2 这种嵌入式计算平台上能把这种“学院派”模型跑起来本身就是一件很有价值的事情。1.2 Jetson TX2 的硬件底气与限制算力强功耗可控接口齐全这是当年 Jetson 系列主打的口号。TX2 搭载了 NVIDIA Pascal 架构的 GPU拥有 256 个 CUDA 核心CPU 部分则是六核双核 Denver 2 四核 Cortex-A57内存统一为 8GB LPDDR4。官方标称的 AI 算力大约 1.33 TFLOPsFP16这个数字在今天看并不高但放在嵌入式设备里已经算不错了。不过硬件再好也要看软件生态怎么配合。TX2 官方支持的 JetPack 系统最高版本是 JetPack 4.6.x它内置的是 Ubuntu 18.04、CUDA 10.2、cuDNN 8.x 和 TensorRT。这意味着如果你想跑新版本的 PyTorch比如 1.13 以上会发现预编译包基本都是给 x86_64 平台的TX2 的 aarch64 架构只能自己用源码编译过程相当折腾。所以我的策略是直接走 OpenPose 的 Caffe 分支——它和 TX2 上的 CUDA 10.2 时代完美匹配编译链相对成熟网上可参考的案例也更多。1.3 我给自己定的目标在和这块板子“斗智斗勇”之前我先明确了自己的技术验证目标这能帮我在后续决策中少走弯路在 TX2 上编译 OpenPose 的 Caffe 版本成功运行自带示例用 USB 摄像头做本地实时推理验证关键点检测效果测试不同输入分辨率和不同模型BODY_25、COCO对帧率的影响确认实际可用性记录常见报错和解决办法方便后来者直接“抄作业”。这样哪怕最终不能做到 30FPS 实时我也能给出一个真实的、可复现的性能基线而不是单纯靠搜来的“应该能跑”下结论。2. 方案选型与依赖解析2.1 为什么选 JetPack 4.6 而不是新版系统说实话我也曾动过给 TX2 刷 Ubuntu 20.04 甚至 22.04 的念头毕竟新版操作系统在软件包上更友好。但实际搜了一圈TX2 的官方 BSPBoard Support Package停在了 JetPack 4.6刷 Ubuntu 20.04 需要自己移植内核和设备树WiFi 模块、硬件编解码器、风扇控制这些都可能失效。对于想专注跑 OpenPose 的人来说折腾系统带来的收益远小于风险。所以我的建议非常直接用官方 JetPack 4.6 刷机不要在系统版本上特立独行。JetPack 4.6.4 是 TX2 支持列表里比较靠后的一个版本里面自带的 CUDA 10.2、cuDNN 8.2、TensorRT 8.2 完全能满足 OpenPose Caffe 编译需求。就算以后想跑 TensorRT 加速也不需要额外折腾。刷机过程不再赘述简单说就是用一台 Ubuntu x86 主机安装 SDK Manager用 Type-C 数据线把 TX2 切到 Recovery 模式连接主机按照提示烧录系统。如果手里没有现成的主机也可以找厂家提供的预刷镜像但要确认镜像的 JetPack 版本。2.2 OpenPose 分支选择的讲究OpenPose 的官方 GitHub 仓库主要维护的是 Caffe 和 PyTorch 两个实现路径。在 TX2 上我选择了官方 Caffe 分支原因是Caffe 分支的依赖项简单直接CUDA、cuDNN、OpenCV、Protobuf、GFlags、GLog这些在 Ubuntu 18.04 源里都有官方仓库的 doc/installation.md 提供了比较详细的编译指引网上用户也多遇到问题容易查到Caffe 版本对显存占用相对友好在 8GB 统一内存的 TX2 上更适合做实时推理。而 PyTorch 版本虽然模型更丰富、生态更现代但 TX2 上编译 PyTorch 本身就是个大工程而且推理时的开销通常比 Caffe 高。考虑到验证目的是“把 OpenPose 跑起来”我选择先用 Caffe 版本打通链路。以后若是要换算法再考虑 TensorRT 部署也不迟。2.3 依赖库版本清单与选择理由在 TX2 上我们不能像在 PC 上那样随便 pip install 或者 apt install 最新版本因为很多库需要和 CUDA 算力、ARM 架构匹配。我最后锁定的关键依赖如下组件推荐版本选择说明JetPack4.6.4TX2 官方支持的最高版本自带 CUDA 10.2CUDA10.2与 Caffe 编译链兼容性最好官方文档大量示例基于此版本cuDNN8.2.1JetPack 自带无需单独安装OpenCV4.1.1系统自带JetPack 已预编译带 CUDA 支持直接用省事Protobuf3.21.12源码编译系统自带 3.0 版本过低OpenPose 要求 3.1建议源码装CMake3.10.2 以上Ubuntu 18.04 自带版本即可CaffeOpenPose 仓库内嵌自带大量修改不要直接使用 Caffe 原版为什么 Protobuf 要单独编因为 OpenPose 在生成 protobuf 头文件时会用到较新版本的功能而 Ubuntu 18.04 自带的 libprotobuf 是 3.0 左右编译模型定义时会报一堆google/protobuf相关错误。我后面会给出具体的编译方法。2.4 显卡驱动的坑位预警热词里反复出现“nvidia-smi has failed because it couldnt communicate with the nvidia driver”这类问题在 TX2 上其实也类似JetPack 刷好后如果你在终端里执行nvidia-smi可能会看到驱动通信失败。这不是因为你没装驱动而是 TX2 的板级 CUDA 驱动和 x86 桌面版不同nvidia-smi工具本身不一定被安装或正确链接。解决办法有两个确认/usr/lib/aarch64-linux-gnu/libcuda.so是否存在以及/usr/local/cuda-10.2是否有完整文件如果需要nvidia-smi可以安装nvidia-jetpack包里的nvidia-smi组件或者使用tegrastats命令查看 GPU 使用率、温度等更符合嵌入式平台的信息。我自己的做法是直接放弃nvidia-smi统一用tegrastats、nvpmodel、jetson_clocks这套工具来管性能和功耗。这样既避免了驱动通信报错也更贴合 TX2 的使用习惯。3. 编译部署与实操细节3.1 系统初始化和环境变量设置刷完 JetPack 4.6.4 后第一件事就是打开终端把软件源换成能用的国内镜像否则 apt update 能等到天亮然后安装编译必需的基础工具sudo apt update sudo apt install -y cmake git g wget unzip接着确认 CUDA 环境变量。JetPack 默认把 CUDA 装在/usr/local/cuda-10.2并且会在/etc/profile.d/里放一个环境脚本。但保险起见我在~/.bashrc里加了一段export PATH/usr/local/cuda-10.2/bin:${PATH} export LD_LIBRARY_PATH/usr/local/cuda-10.2/lib64:${LD_LIBRARY_PATH} export CUDA_HOME/usr/local/cuda-10.2 source ~/.bashrc然后执行nvcc -V验证看到 10.2 版本信息才算环境就绪。提示TX2 的 JetPack 会自动将 CPU/GPU 频率设置为动态模式刷机后跑大型编译可能会触发降频。建议在编译前手动开启高性能模式命令是sudo nvpmodel -m 0最大性能模式需要的话再执行sudo jetson_clocks锁定风扇和频率。这对编译速度影响非常明显。3.2 编译新版 Protobuf 解决版本冲突我遇到的头一个问题就是 Protobuf 版本过低。OpenPose 在生成 caffe.proto 相关代码时如果依赖库版本不对会报缺少google/protobuf/port_def.inc之类的错误。在 TX2 上最稳妥的方式是源码编译。我的步骤如下wget https://github.com/protocolbuffers/protobuf/releases/download/v3.21.12/protobuf-cpp-3.21.12.tar.gz tar -xzf protobuf-cpp-3.21.12.tar.gz cd protobuf-3.21.12 ./configure --prefix/usr make -j6 sudo make install sudo ldconfig这里关键参数是--prefix/usr这样头文件会安装到/usr/include/google/protobuf库文件到/usr/libCMake 查找时不容易撞上旧的系统包。如果安装在/usr/local下后续别的库在搜索时可能出现路径不一致的问题。装完后执行protoc --version正常会输出libprotoc 3.21.12。3.3 编译 OpenPose 的 Caffe 分支因为 OpenPose 的 Caffe 是内嵌在仓库里的所以不能直接 pip 或者 apt 安装必须用官方 Caffe 子模块编译。我使用的是 OpenPose 官方仓库里的caffe分支整体编译方法如下git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git cd openpose git submodule update --init --recursive --remote子模块拉取过程比较慢因为 Caffe 仓库本身就不小。如果你用的网络环境不稳定可以多试几次或者用代理加速 git 下载。不过这里要说明下载慢是网络问题和板子本身性能无关。接下来在openpose/目录下新建build文件夹用 CMake 配置构建。这一步非常关键我直接给出我验证过的配置命令cd openpose mkdir build cd build cmake -D CMAKE_BUILD_TYPERelease \ -D CMAKE_INSTALL_PREFIX/usr/local/openpose \ -D BUILD_CAFFEON \ -D CUDA_TOOLKIT_ROOT_DIR/usr/local/cuda-10.2 \ -D OpenCV_DIR/usr/lib/aarch64-linux-gnu \ -D BUILD_PYTHON_APIOFF \ -D BUILD_EXAMPLESON \ -D BUILD_DEMOON \ ..解释一下几个关键参数BUILD_CAFFEON让 OpenPose 构建时顺带编译内置 Caffe不用额外手动编译OpenCV_DIR指向系统 OpenCV 的 CMake 配置目录。JetPack 自带 OpenCV 4.1.1通常在/usr/lib/aarch64-linux-gnu/下BUILD_PYTHON_APIOFF我这次先用 C demo 验证不开 Python 接口。如果后续想用 Python 写脚本这个开关要打开但需要额外配置 Python 环境容易踩坑BUILD_DEMOON生成直接运行图片/摄像头/视频的示例程序。然后开始编译make -j6注意TX2 虽然有六核 CPU但内存只有 8GB编译时-j6可能让内存吃到 90% 以上有概率触发 OOM。如果你用htop看到内存即将耗尽就改成make -j4。编译时间大约 40-60 分钟取决于网络和机器温度。编译完后再执行sudo make install这一步会把 OpenPose 的头文件、库和示例程序安装到/usr/local/openpose。我在实际编译中第一次用-j6就在 Caffe 的数学库部分触发了 OOM直接改成-j4后就平稳通过了。建议你先用-j4起步编译到一半看内存占比合适再继续加线程。3.4 下载预训练模型OpenPose 的预训练模型并不会随仓库一起下载运行时会根据配置自动去下载但 TX2 上的网络状况未必理想建议手动下载并放置到指定目录。模型目录默认为/usr/local/openpose/models/或者源码目录openpose/models/。需要下载的模型有 BODY_25、COCO 和 MPII 三套每套都包括.prototxt和.caffemodel文件。官方提供了一键下载脚本cd openpose/models ./getModels.sh不过这个脚本会一次下载所有模型体量不小。如果你空间有限可以只下载 BODY_25 和 COCO 模型。BODY_25 是 OpenPose 自家定义的 25 个关键点格式比 COCO 的 18 点多出了脚部关键点对动作捕捉类应用更友好COCO 则更适合和其他 COCO 预训练模型做对比。模型文件较大下载时一定要确认文件完整性否则运行时会提示Check failed: proto.ParseFromString之类的错误。3.5 运行图片和摄像头示例模型就位后先用一张包含人物的图片测试cd /usr/local/openpose ./build/examples/openpose/openpose.bin \ --image_dir /path/to/your/image.jpg \ --write_images /path/to/output \ --model_folder /usr/local/openpose/models \ --net_resolution 320x176--net_resolution是推理时输入网络的尺寸这里设置为 320x176是 OpenPose 官方推荐的较低分辨率速度更快。实际输出图里会叠加上关键点骨架。如果图片里有单个人物且光线正常几秒内就能看到结果。验证图片没问题后我再接上 USB 摄像头测试实时视频流./build/examples/openpose/openpose.bin \ --camera 0 \ --net_resolution 320x176 \ --model_folder /usr/local/openpose/models \ --write_json /path/to/output_json--camera 0表示使用编号为 0 的摄像头设备。这里要注意 TX2 板载 CSI 摄像头和 USB 摄像头的设备编号不同用 USB 摄像头一般就是 0。运行后屏幕上会出现一个窗口实时显示检测结果终端里也会打印每个关键点的坐标。第一次跑通时看到骨架贴上人像的那一刻确实挺有成就感的。4. 性能调优与实测经验4.1 分辨率对帧率影响到底有多大OpenPose 的推理速度在很大程度上取决于网络的输入分辨率而不是原始摄像头分辨率。官方 COCO 模型的默认网络分辨率是 656x368在 TX2 上跑这个尺寸基本是幻灯片级别帧率可能只有 2-3 FPS。但降到 320x176 后能明显提升到 10 FPS 左右肉眼可见流畅度上了一个台阶。网络上各种参数组合很多我自己整理了一份在 TX2 上比较典型的帧率参考网络分辨率模型平均帧率TX2高性能模式CPU占用观感656x368COCO2-3 FPS偏高卡顿明显432x240COCO5-6 FPS中高可用但不够顺滑320x176BODY_258-10 FPS中等适合简单交互256x144COCO10-12 FPS中等快速预览精度下降我实测下来320x176 是 TX2 上精度和速度最平衡的选择既能保证关键点基本不漂移也能跑出接近实时的帧率。如果再往下降关键点位置的误差就会变得肉眼可见在动作识别场景里会产生严重的抖动。顺带说一句CPU 频率和 GPU 频率也会影响帧率。我在运行前把nvpmodel -m 0和jetson_clocks都打开后帧率比默认模式高了大约 30%代价是发热和功耗上升。如果设备是电池供电可以根据实际热量情况调整。4.2 模型选择策略BODY_25 vs COCO vs MPIIOpenPose 官方提供了多套模型在 TX2 上跑的时候模型的选择直接影响检测效果和速度BODY_2525 个关键点包含了脚底、脚踝等更精细的部位适合做步态分析、康复训练在 TX2 上速度和精度平衡较好COCO18 个关键点只到脚踝为止适合做通用的人体检测和人机交互网络结构相对简单帧率略高MPII16 个关键点但代码库更新较少一般不建议在 TX2 上优先使用。我最后在摄像头 demo 里固定用的是 BODY_25因为它对肢体末端的检测更稳定在动作计数场景里能减少漏检。4.3 后面可以怎么进一步提速如果你不满足于 10 FPS想往 15 FPS 以上冲可以考虑以下几条路TensorRT 推理OpenPose 官方没有直接支持 TensorRT但社区有人把 Caffe 模型转换成 TensorRT 的 engine 文件转换后单帧推理时间能缩短到 30-50ms对应帧率在 20 FPS 以上。缺点是转换过程有些繁琐而且模型精度会有微小损失剪枝和量化在边缘设备上做 INT8 量化可以大幅提升吞吐量但需要重新校准模型对关键点回归任务而言精度损失会更明显限制检测人数OpenPose 默认最多检测 16 个人如果只做单人或双人检测把--number_people_max调小能省下不少后处理时间。我尝试过把--number_people_max 1设置为单人间检测在同样分辨率下帧率提升了 10-15%对于单人健身应用来说这种改动几乎没有代价。4.4 功耗与温度控制经验TX2 的 8GB 统一内存在推理时会被 CPU、GPU 共享OpenPose 运行过程中内存占用经常超过 5GB。如果同时开图形界面、摄像头和录像很容易被系统 OOM killer 杀掉进程。我的建议是跑推理时用 SSH 连接 TX2关闭图形界面相关的高占用进程或者至少不要在本机开太多 GUI 程序。温度方面TX2 在长时间高负载下核心温度会逼近 90 度。如果机箱没有主动散热OpenPose 跑十几分钟后就会出现明显降频帧率直接从 10 FPS 跌到 5 FPS。解决办法是加装调速风扇或者定期清理散热片上的灰。我在机箱外加了个 5V 风扇对着散热片吹温度能稳定在 70 度左右帧率稳定很多。5. 常见问题与排查实录5.1 驱动通信失败该怎么办热词里频繁出现的“nvidia-smi has failed because it couldnt communicate with the nvidia driver”在 TX2 上我第一次也碰到了。一开始我还以为要重刷驱动后来排查发现JetPack 默认并没有安装nvidia-smi命令执行它时会去读 x86 平台的 PCIe 设备信息而 TX2 的 GPU 是集成在 SoC 里的两者机制不一样。解决办法如果你只是想看 GPU 使用率直接执行sudo tegrastats会实时打印 GPU 频率、内存占用、温度如果你确实需要nvidia-smi的输出格式执行sudo apt install nvidia-smi它可以从 JetPack 库中安装 ARM 版不要照着 x86 桌面的教程手动装驱动那极有可能把系统搞崩。顺带说一句nvcc -V能正常显示 CUDA 版本说明 CUDA 工具链是好的驱动通信报错并不影响编译和运行。5.2 编译时报 protobuf 版本冲突编译 OpenPose 时如果报以下错误基本都是系统 Protobuf 版本太低/usr/include/google/protobuf/message.h:xxx: error: ‘GetDescriptor’ is protected within this context不用挣扎直接把系统 Protobuf 升级到 3.21.12 就好。注意升级后要重新执行sudo ldconfig有些老库会被覆盖如果别的程序依赖旧版 protobuf可能会受影响。不过对于只跑 OpenPose 的板子来说这个风险可忽略。5.3 运行时报模型加载失败如果运行 OpenPose 时提示找不到.caffemodel文件或者直接闪退先检查模型目录下有没有对应文件ls -lh /usr/local/openpose/models/pose/body_25/ ls -lh /usr/local/openpose/models/pose/coco/然后再看文件大小如果只有几 KB几乎就是下载中断导致的文件损坏重新用wget -c断点续传或者重新下载即可。还有一种情况是.prototxt路径写错运行时通过--model_folder指定目录即可。我习惯用绝对路径避免相对路径引发的“找不到模型”问题。5.4 OpenCV 摄像头打不开怎么办TX2 上跑 USB 摄像头最常遇到的是VideoCapture(0)打开失败或者画面黑屏。排查思路先用ls /dev/video*看设备节点是否存在运行 OpenPose 时用--camera 0有的摄像头设备是/dev/video1而不是/dev/video0需要多试几个编号用v4l2-ctl --list-devices查看摄像头能力确认其输出格式是否被 OpenCV 兼容避免同时打开两个图形程序抢占摄像头设备。TX2 的 CSI 摄像头比如 Jetson 配套的 IMX219不能在 OpenPose 里直接用--camera 0这样调用需要走 GStreamer 管道。如果你用的是 CSI 摄像头建议先换成 USB 摄像头验证流程省下的时间远比想象中多。5.5 内存不足导致进程被杀OpenPose 在默认配置下会预分配比较大的内存TX2 的内存只有 8GB跑高分辨率网络时很容易 OOM。常见的错误信息是Killed或者std::bad_alloc。解决办法有几个方向降低--net_resolution这是立竿见影的方法减少--number_people_max默认 16 人太激进关闭 OpenCV 的高分辨率窗口显示只在终端打印检测结果提前清理后台无用的进程。我在反复测试中发现如果把网络分辨率设为 432x240、同时检测人数上限设为 2内存峰值大约在 4.5GB 左右运行很稳定。6. 谈谈实际使用中的心得与调整方向跑通 OpenPose 只是第一步真正把一个姿态估计模型用起来需要考虑的不只是帧率。这块 TX2 在测试中暴露出来的最大短板其实是内存带宽GPU 计算不是唯一瓶颈数据在 CPU 和 GPU 之间搬运同样是开销大户。我在实际使用中慢慢摸索出一套比较顺手的流程先用 OpenPose 的 Caffe 版本验证算法效果然后根据自己的场景需求把人体的关节点坐标输出为 JSON丢掉可视化窗口这样不仅省了 CPU 渲染开销整个系统的稳定性也高了很多。如果以后需要更高帧率我会把模型转成 TensorRT 再试一轮但目前来看10 FPS 的骨架输出对于很多低速动作分析场景是够用的。另外TX2 的散热真的很重要。我把板子从原来的宽松外壳里换到一个带风扇的金属壳里温度和帧率表现都有了质的提升。嵌入式设备跑深度学习不是只要代码能运行就结束的硬件层面的调优往往比软件层面更立竿见影。最后再分享一个实用小技巧OpenPose 的--write_json参数可以把每个关键点坐标和置信度实时写入 JSON 文件就算你关掉图形窗口数据也不会丢。做后处理时我用 Python 脚本监控那个 JSON 目录每次有新的文件产生就立刻解析相当于直接绕过了 OpenPose 的 Python API省去了编译 Python 绑定的麻烦。这个方法在无人值守的长时采集场景里特别管用你们也可以试试。
返回列表