尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Win10复现OpenPose+ST-GCN动作识别:从环境搭建到踩坑实战

Win10复现OpenPose+ST-GCN动作识别:从环境搭建到踩坑实战 1. 先搞清楚这套组合的逻辑为什么是OpenPose ST-GCN如果你能搜到这个标题大概率已经看过前两篇关于姿态估计和动作识别的基础内容了。OpenPose负责从视频帧里提取人体关键点坐标ST-GCN再把这些关键点序列当成图结构数据去分类两者前后衔接正好组成一条完整的“视频动作识别”pipeline。这篇文章不聊理论推导只聊怎么在Win10上把OpenPose 1.7.0和ST-GCN的代码完整复现出来包括编译、跑通demo、数据对接和踩坑记录。我默认你是有一定Python基础的至少会装包、改环境变量也大概知道CUDA是干什么的。但我不默认你熟悉C和CMake因为OpenPose在Windows上的编译过程确实拦住了很多人。这篇文章会把从零到一的每一步都拆开讲命令、参数、日志现象都给你列出来你照着操作比看十篇零散教程都管用。1.1 这套模型组合到底在解决什么问题先说清楚一个概念动作识别不是图像分类它面对的是“一段视频里某个人在做什么动作”这个问题。输入不是单张图片而是一段时间内的多帧图像输出也不只是“有没有人”而是“这个人在做什么”比如走路、挥手、坐下、摔倒。做这件事有两条技术路线一条是基于RGB图像的时序模型典型代表是SlowFast、TSN这类另一条就是先做姿态估计把每个人的骨骼关键点提取出来再对关键点序列做分类OpenPose ST-GCN就是这条路线里的经典组合。为什么要绕一圈去提取骨骼再分类因为骨骼关键点去掉了背景、衣服、光照这些干扰信息模型学的是“关节角度和位置关系的变化模式”泛化能力更强。而且骨骼数据是低维的计算量比直接处理视频帧小很多。做过实际项目的人都知道工业场景里动作识别经常要跑在边缘设备上骨骼方案的实际部署成本低得多。OpenPose 1.7.0支持2D人体关键点检测单人最多能出25个关键点BODY_25模型多人场景也能处理。ST-GCN全称是Spatial Temporal Graph Convolutional Network它把每一帧的骨骼关键点看成图的节点关键点之间的自然连接关系看成边再把时间维度上的帧间连接也考虑进去用图卷积来提取空间特征用时序卷积来提取运动特征最终输出动作类别概率。简单说OpenPose负责“看到人”ST-GCN负责“看懂动作”。1.2 为什么选择Win10原生环境而不是WSL或虚拟机很多教程推荐在Ubuntu下跑OpenPose和ST-GCN毕竟这两个项目的主要测试环境都是Linux。但这篇文章的主角是Win10而且我可以负责任地说在Win10原生环境复现这套代码比用WSL和虚拟机更省心。先说虚拟机。VirtualBox这类虚拟化方案最大的问题是GPU透传。OpenPose和ST-GCN的推理和训练都要用CUDA虚拟机里要么无法访问物理显卡要么性能损失巨大跑起来比CPU还慢。你想用VMware装个Win10再在里面跑CUDA基本是给自己找麻烦。所以虚拟机方案直接排除。再说WSL2。WSL2虽然支持CUDA转发OpenPose也能在WSL2里通过vGPU跑但你会遇到几个很尴尬的问题OpenPose的demo程序要弹出GUI窗口显示检测结果WSL2要配置Windows的X Server才能弹出图像界面摄像头读取、视频文件路径映射也是坑Python环境的OpenCV还要额外处理显示后端。这些都不难但叠加在一起非常消耗耐心刚开始复现项目的人很容易在这一步就放弃了。相比之下Win10原生环境的优势很明显Visual Studio的MSVC编译器是OpenPose官方支持的构建工具链CMake能直接识别OpenPose官方提供了完整的Windows编译文档Python版本、CUDA版本、cuDNN版本在Windows下都有成熟的搭配方案。只要你照着正确版本装编译过程虽然长但每一步都是可控的。1.3 版本选型与软硬件要求复现老代码版本锁死是第一原则。OpenPose 1.7.0官方明确支持CUDA 10.x和CUDA 11.x的部分版本但考虑到ST-GCN的官方实现是基于TensorFlow 1.x的这里有个很重要的兼容性约束TensorFlow 1.14到1.15版本需要CUDA 10.0或10.1以及cuDNN 7.6。所以我把整套环境的版本都锁定在CUDA 10.1 cuDNN 7.6上这样OpenPose和ST-GCN都能兼顾。硬件方面建议至少8GB显存的NVIDIA显卡。我实测用的是GTX 1660 Super6GBOpenPose单帧推理大概50到80毫秒ST-GCN推理一个动作序列不到50毫秒。如果你的显卡是RTX 20系或30系记得要注意显卡驱动版本必须支持CUDA 10.1。RTX 30系是可用的只是编译的时候需要额外注意算力参数后面编译章节我会具体讲。软件清单先放在这里后面会逐个安装Windows 10 64位系统建议更新到较新的版本Visual Studio 2019Community版即可必须安装C桌面开发组件CMake 3.14以上版本我用的3.20Git for WindowsPython 3.6或3.7推荐3.6ST-GCN的依赖更稳CUDA 10.1 cuDNN 7.6.5OpenPose 1.7.0源码ST-GCN源码yysijie/st-gcn这里特别说明一下为什么不用Python 3.8以上。OpenPose 1.7.0的Python API编译时需要匹配Python的版本Python 3.8也能编译成功但ST-GCN官方代码依赖的TensorFlow 1.15在Python 3.8下兼容性很差经常报“module ‘tensorflow’ has no attribute ‘random_uniform’”之类的错误。为了少踩坑我建议你卸载高版本Python老老实实装一个Python 3.6用conda管理环境最省事。2. 搭建复现环境Win10系统准备与工具链安装环境搭建阶段花的时间往往比跑通代码本身还多。这个阶段急不得每一步做完都值得停下来确认一遍结果不然到了编译阶段一个环境变量配置错误会让你反复横跳。2.1 系统层面的Windows优化与安全中心处理先说一个很多人第一次编译C项目都会遇到的问题Windows安全中心把编译生成的exe或dll文件当成威胁清掉了。OpenPose在编译过程中会生成几十个exe和dll文件Windows的实时保护偶尔会把其中某些文件判定为可疑程序特别是当你第一次运行时Defender的云检查还没认识这些文件。处理思路不是把实时保护全部关掉而是把工程目录加入白名单。具体操作打开Windows安全中心选择“病毒和威胁防护”点击“管理设置”在“排除项”里把OpenPose的源码目录和STM32开玩笑是ST-GCN的目录都加进去。这样既不牺牲全局安全性又避免构建产物被误删。另外建议你检查几个系统配置开启Windows的长路径支持。OpenPose和ST-GCN的源码目录结构很深有些文件路径超过260字符会引发git clone失败。通过组策略开启WinR输入gpedit.msc进入“计算机配置 → 管理模板 → 系统 → 文件系统 → 启用Win32长路径”设置为“已启用”。电源计划设为“高性能”。编译是吃CPU的活笔记本用户如果不插电编译一个项目可能要跑四十分钟以上电源计划会明显影响编译速度。关闭UAC弹窗干扰。编译过程中VS和CMake会自动弹出大量确认框建议把UAC级别调到最低等全部跑完再调回来。2.2 必备工具链安装细节Visual Studio 2019安装的时候工作负载勾选“使用C的桌面开发”右侧安装详细信息里确认勾选以下组件MSVC v142 - VS 2019 C x64/x86生成工具、Windows 10 SDK、C CMake工具。CMake工具可以不在VS里装后面我们单独安装CMake GUI。CUDA 10.1的安装需要注意安装前先确认NVIDIA显卡驱动版本不要太新。这是个很反直觉的点太新的驱动不一定兼容老版本CUDA Toolkit。如果驱动版本太新导致CUDA 10.1的固件不兼容安装的时候会报错个别情况装完以后运行还会出现奇怪的问题。我个人的经验是驱动版本在441到452左右对CUDA 10.1是最稳的。cuDNN安装相对简单解压后把cuda文件夹下的bin、include、lib\x64三个目录里的文件分别复制到CUDA安装目录C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1对应的bin、include、lib\x64目录下。装完以后建议验证CUDA环境。命令行输入nvcc --version正常会输出CUDA 10.1版本的编译信息。再写一个简单的测试脚本验证运行时是否正常或者直接编译OpenPose的时候再验证——反正第一步过不去的话CMake配置阶段一定会报错。2.3 为什么版本锁定这么重要我知道肯定有人会用最新的CUDA 12.x去试然后跑来问为什么编译失败。道理其实很简单OpenPose 1.7.0是2020年发布的它内部依赖的Caffe框架和第三方库如Caffe、OpenCV都是按当时的CUDA版本适配的。ST-GCN官方实现更老TensorFlow 1.15的时代是2019年连Python 3.7都算新版本。老代码配老版本不是保守是实用性考虑。你复现这个项目是为了理解动作识别的完整流程而不是为了给开源项目做版本适配。把这套环境跑顺之后你已经有足够经验去迁移到更新的实现上了。还有一个小建议所有软件安装路径、项目路径、模型路径都避免中文和空格。OpenPose的CMake脚本对空格路径的处理虽然优化过但ST-GCN的Python代码读文件时中文路径经常触发编码问题。我见过太多人因为用户名叫“张三”就把整个项目放到C:\Users\张三\目录下最后在读取模型文件时各种解码报错。实在没办法的话把项目直接放在D盘根目录比如D:\ActionRecognition\。3. 编译OpenPose 1.7.0CMake配置到VS2019构建OpenPose在Windows上的编译是这套流程里最劝退、但其实也最套路化的环节。只要版本匹配CMake配置正确剩下的就是等编译完成。3.1 下载源码与模型从GitHub克隆OpenPose源码git clone https://github.com/CMU-Perceptual-Computing-Lab/openpose.git cd openpose git checkout v1.7.0注意一定切到v1.7.0标签不要用master分支。master分支经历了后续更新和ST-GCN对接时有些API变动但复现文章还是按照1.7.0来说更稳妥。OpenPose在首次运行时会自动下载模型文件但自动下载经常因为网络原因失败。我的做法是提前手动下载好所需模型放到指定目录。需要下载的模型主要是这几个以BODY_25为主pose_iter_440000.caffemodelBODY_25模型hand_pose_iter_102000.caffemodel手部关键点模型face_pose_iter_116000.caffemodel面部关键点模型把下载好的模型文件放到model目录下OpenPose源码目录里本来就有对应的文件夹结构比如model/pose/body_25/。放好后运行OpenPoseDemo就不会再触发自动下载了。3.2 CMake配置参数逐项说明打开CMake GUI设置源码目录为OpenPose的根目录构建目录建议设置为源码目录下的build文件夹。第一次点击Configure之前需要先选择生成器。选“Visual Studio 16 2019”平台选择“x64”。这里有个常见的坑如果你没选x64默认可能是x86后面编译出来的是32位程序加载不了64位的CUDA库直接报一堆“无法解析的外部符号”错误。Configure完成之后重点检查以下选项BUILD_PYTHON_API勾选我们需要Python接口BUILD_EXAMPLES勾选方便测试demoBUILD_CAFFE勾选OpenPose自带Caffe编译时一起编USE_CUDA勾选USE_CUDNN勾选USE_OPENCV勾选GPU_MODE选择CUDACUDA_ARCH这里要填你的显卡算力对应值。GTX 1660 Super是7.5RTX 20系是7.5RTX 30系是8.6。如果填错编译能过但运行时可能报“no kernel image is available for execution on the device”如果你没有OpenCV让CMake自动下载OpenCV也行但下载速度慢且容易失败。我更推荐手动下载OpenCV 4.1或4.2版本解压后在CMake里手动设置OpenCV_DIR为opencv/build目录。这个路径一定要精确到包含OpenCVConfig.cmake的目录。再次点击Configure直到没有红色警告然后点Generate生成VS解决方案。3.3 VS2019编译与运行实测用VS2019打开build目录下的OpenPose.sln解决方案配置选择“Release”平台选择“x64”右键点击解决方案选择“生成解决方案”。这里提醒一下首次编译时间很长取决于CPU性能一般20到50分钟。中间可能有一两次报错先别慌很多报错是环境问题不是代码问题。常见的“找不到Python.h”错误是因为CMake的Python路径没有指向正确环境常见的“C2220: 警告被视为错误”需要改一下VS的警告设置把警告不作为错误即可。编译完成后OpenPoseDemo.exe会生成在build\x64\Release目录下。测试一张图片cd build\x64\Release .\OpenPoseDemo.exe --image ../../../examples/media/COCO_val2014_000000000192.jpg --write_images output/如果一切正常output目录下会生成带骨骼连线标注的图片。第一次看到输出图的时候说明OpenPose已经跑通了。测试视频识别.\OpenPoseDemo.exe --video ../../../examples/media/video.avi --write_video output_video.avi注意视频文件路径换成实际存在的文件。如果视频文件本身有问题OpenPoseDemo会卡住不动看起来像死机其实是在等待视频解码库响应。建议先用OpenCV自带的视频文件或者自己用ffmpeg转成MP4再试。3.4 调用OpenPose Python APIOpenPose的C推理接口用起来不方便后续果然要喂数据给ST-GCN必然要通过Python调用。编译完Python API之后需要在环境变量里加入OpenPose的Python绑定路径build/python/openpose/Release build/x64/Release第一个目录里有pyopenpose.pyd第二个目录里有OpenPose的dll。不加入这两个路径import pyopenpose会直接报“ModuleNotFoundError: No module named ‘pyopenpose’”。测试Python APIimport sys import cv2 sys.path.append(D:/ActionRecognition/openpose/build/python/openpose/Release) sys.path.append(D:/ActionRecognition/openpose/build/x64/Release) # 设置环境变量 import os os.environ[PATH] os.environ[PATH] ;D:/ActionRecognition/openpose/build/x64/Release import pyopenpose as op params dict() params[model_folder] D:/ActionRecognition/openpose/models/ params[face] False params[hand] False opWrapper op.WrapperPython() opWrapper.configure(params) opWrapper.start() image cv2.imread(D:/ActionRecognition/openpose/examples/media/COCO_val2014_000000000192.jpg) datum op.Datum() datum.cvInputData image opWrapper.emplaceAndPop([datum]) print(检测到的人体关键点数, len(datum.poseKeypoints)) cv2.imwrite(python_output.jpg, datum.cvOutputData)运行后终端会打印检测到的人数信息同时当前目录生成python_output.jpg。这就是OpenPose在Python里跑通的标志。这里有个容易踩的坑系统里有多个Python环境时pyopenpose.pyd绑定的Python版本必须和运行环境的Python版本一致。如果你用Python 3.6编译的OpenPose就必须用Python 3.6解释器运行换Python 3.9会直接报错“ModuleNotFoundError”或者加载失败。4. 复现ST-GCN骨架动作分类模型跑通OpenPose拿到人体关键点之后下一步就是让ST-GCN学会识别“这段骨架序列在做什么动作”。4.1 ST-GCN的原理与输入数据格式ST-GCN的核心思想是把骨架序列构造成一个时空图。每一帧里人体关键点之间的连接关系构成空间边相邻两帧之间同一个关键点的连接构成时间边。图卷积在空间上聚合邻接节点的信息时序卷积在时间上捕捉运动的动态变化。ST-GCN的输入数据维度是(样本数, 通道数, 帧数, 关键点数, 人数)。通道数通常是3对应x坐标、y坐标和置信度。帧数就是一个动作序列持续了多少帧关键点数就是每个骨架包含多少个点人数表示一个样本里最多有几个人。OpenPose输出的poseKeypoints数组格式是(人数, 关键点数, 3)前两维是x和y坐标第三维是置信度。你需要把自己采集的数据转成ST-GCN的格式这一步叫数据预处理或者packing。4.2 安装依赖与源码准备ST-GCN官方实现地址是https://github.com/yysijie/st-gcn但这个仓库的代码版本比较老直接clone下来在新环境里跑会碰到不少问题。我的建议是clone到本地之前先创建好独立的环境。用conda创建Python 3.6环境conda create -n stgcn python3.6 conda activate stgcn然后安装依赖pip install tensorflow-gpu1.15.0 pip install numpy1.17.4 pip install scipy1.2.1 pip install opencv-python4.1.2.30 pip install matplotlib pip install tqdm pip install pandas注意版本numpy的版本尤其重要。TensorFlow 1.15和numpy 1.17是配套的如果你直接装最新版numpy跑数据增强时会出现“cannot import name ‘imread’”或者“module ‘numpy’ has no attribute ‘math’”这类问题。4.3 数据准备小规模跑通与NTU数据集ST-GCN官方支持两个数据集NTU RGBD和Kinetics-Skeleton。NTU RGBD是动作识别领域的标准数据集有60类动作、几万样本但完整下载需要超大空间和很长的下载时间。如果是第一次复现我不建议直接把完整数据集搬下来——你更需要先验证代码流程能跑通。Kinetics-Skeleton数据集相对小一些仓库的data文件夹下有它的数据划分文件包括train和val的样本列表。把数据集下载好放到data/kinetics_skeleton目录然后运行训练脚本验证。如果网络下载数据也不是很方便还有一个取巧路径自己用OpenPose在几段包含动作的视频上提取骨架构造一个几十个样本的小数据集。虽然准确率不会高但足以验证整个链路是通的。具体做法用OpenPose把每帧的关键点提取出来保存成npy数组然后按ST-GCN的输入格式打包。我个人建议的流程是先下载Kinetics-Skeleton中的一小部分数据例如只取前10类动作、每类几十个样本放到data目录里修改处理脚本的路径快速验证训练和测试都能跑通。这个流程走得通再考虑完整数据集。4.4 训练与测试实操ST-GCN仓库里提供了训练和测试的入口脚本main.py。训练前先确认配置文件在config目录下找到st_gcn.kinetics-skeleton.yaml之类的文件把数据集路径、显卡设置、批次大小、训练轮数等参数改好。启动训练python main.py --train --config config/st_gcn.kinetics-skeleton.yaml训练过程中会看到loss逐渐下降、准确率慢慢提升。这个阶段不需要急着追求高精度重点是确认代码能完整运行一个epoch。测试已训练模型python main.py --test --config config/st_gcn.kinetics-skeleton.yaml如果你只是想把整个流程跑通甚至可以跳过训练直接用官方提供的预训练模型。把下载好的预训练模型放到指定目录修改配置文件指向它然后跑测试即可。测试完成后输出中会打印每个动作类别的准确率、recall、f1-score等指标。看到这些指标的那一刻说明OpenPose ST-GCN这套链路已经完整接通了。5. 关键报错与排查记录写到这里我认为最值得你保存的是这一节。下面是我在复现过程中遇到过的报错和排查思路按阶段整理成速查表你遇到问题时可以直接对号入座。5.1 CMake阶段的坑报错“CMake Error: The following variables are used in this project, but they are set to NOTFOUND”这是某依赖库没找到。最常见是OpenCV没有正确指定OpenCV_DIR或者CUDA找不到。逐一查看CMakeError日志找到具体是哪个库没找到手动指定路径。报错“CUDA_cublas_device_LIBRARY NOTFOUND”CUDA 10.1在较新版本CMake下会有这个识别问题。解决方法是手动设置CUDA_cublas_device_LIBRARY路径指向C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\lib\x64\cublas_device.lib。这个坑在官方文档里就有说明属于CMake对旧版本CUDA兼容性的历史遗留问题。报错“Python not found”或“PythonLibs NOTFOUND”CMake默认查找的是最新版本的Python而我们需要的是Python 3.6。在CMake GUI里手动设置PYTHON_LIBRARY为Python 3.6安装目录下的libs\python36.libPYTHON_EXECUTABLE指向python3.6.exe。5.2 编译阶段的坑编译报错“C2220: warning treated as error - no object file generated”VS2019默认把警告当错误导致编译中断。解决方法是打开项目属性 → C/C → 常规 → “将警告视为错误”改为“否”。也可以在OpenPose的CMakeLists里调整这个选项重新生成项目。编译报错“LNK1104: cannot open file ‘python37.lib’”这表明CMake混用了Python版本。你配置的OpenPose可能找到了Python 3.7的库但转换到VS工程后某些子项目指向了错误路径。回到CMake把PYTHON_LIBRARY改成实际安装的版本重新Generate。5.3 运行阶段的坑运行OpenPoseDemo报“Failed to load the model”模型文件路径不对。OpenPose是相对路径查找模型源码根目录启动才行或者用--model_folder参数显式指定。建议启动时加--model_folder D:/ActionRecognition/openpose/models/。运行Python API报“DLL load failed”一种原因是缺少Microsoft Visual C运行库另一种是OpenPose的dll文件路径没加入系统PATH。把build/x64/Release加入PATH后重启终端再试。ST-GCN训练报“Resource exhausted: OOM when allocating tensor with shape[...]”显存不足。降低batch_size或者把num_worker数据预取进程数调小。实在不够把输入帧数调低比如从N150改成N100。5.4 环境匹配速查表组件推荐版本备注Windows10 64位 1909以上开启长路径Visual Studio2019 16.11安装C桌面开发CMake3.20.xGUI版更方便CUDA10.1显卡驱动441.22cuDNN7.6.5需登录NVIDIA官网下载Python3.6.8用conda管理TensorFlow1.15.0ST-GCN依赖OpenPosev1.7.0切到tag再编译OpenCV4.1.2手动指定路径我实际用这套配置跑下来OpenPose推理正常ST-GCN训练和测试正常没有遇到版本不兼容的玄学问题。再补充一个经验如果你用的显卡是RTX 30系CUDA 10.1在运行起来之后可能报“no kernel image available”的错误这是因为CUDA 10.1不支持Ampere架构的算力8.0/8.6这时需要安装CUDA 11.1以上版本但TensorFlow 1.15的兼容性又会下降。两条路要么换一张20系或10系显卡来复现老项目要么放弃ST-GCN官方老代码改用PyTorch实现的ST-GCN复现版。从个人经验看PyTorch版例如microsoft的st-gcn移植用起来更舒心但那就不是这篇标题里说的“复现原始代码”了。建议小白先用老版本跑通流程跑完理解了再迁移到PyTorch版。最后再分享一个实操中的心得体会整套流程跑下来真正卡住人的地方不是模型原理而是环境匹配。当年我在Windows上编译OpenPose时CMake配置反复失败了七八次每次都是老老实实看日志、找依赖、改路径最后一上午才把整个构建链路理顺。等你把这一步迈过去后面无论是换数据集还是换识别模型都会顺畅很多。如果你配环境的时候遇到我这里没有写到的报错不要慌去GitHub的issue区搜关键词大概率有人已经问过同样的问题了。还有一个小技巧建议把每一步安装好的软件版本、下载链接、配置参数都记录在文档里包括环境变量设置、CMake配置项的勾选情况。这个东西在将来重装系统、换机器的时候价值比你想象的大得多。我自己后来换电脑一小时就把这套环境重新搭好了全凭当时的笔记。
返回列表