☰
OpenPose模型文件覆盖与部署指南:caffemodel/prototxt配置及故障排查
2026/10/17 20:30:51 网站建设 项目流程

简介:OpenPose是实时多人姿态估计领域的代表性开源库,这份模型包完整覆盖其models目录下的核心文件,面向需要部署人体、面部、手部关键点检测功能的开发者与行为识别研究者。压缩包内共含16个文件,以prototxt网络定义文件、caffemodel预训练权重文件为主,另搭配sh与bat下载脚本、xml级联分类器以及示例配置文件,整体大小约727.86MB,解压后放入OpenPose对应目录即可自动加载推理。资源内置Face、Hand、Body_25、COCO与MPI五类预训练模型:人脸模型可标记51个面部关键点,适合表情识别与人脸对齐;手部模型输出21个关节位置,可支撑手势控制与虚拟现实交互;Body_25与COCO模型专注全身25点姿态估计,分别基于不同数据集训练,适应复杂背景与多种姿势;MPI模型作为另一套权重,便于对比效果。这些模型均为成熟权重,免去了自行训练的繁琐过程。目前已有918人学习下载,借助这套资源可快速搭建OpenPose环境,用于动作捕捉、运动分析、人机交互等实际项目,也可结合TensorFlow、PyTorch等框架进行二次开发。

1. OpenPose 骨架行为识别卡在哪:模型文件与目录覆盖

很多做 openpose 骨架行为识别的人,代码写好、依赖装完,最后栽在模型文件上。官方脚本下载到一半断掉,或者运行目录不对,Caffe 直接报 Read failed,整个程序起不来。这套 openpose-models 解决的就是这个问题——把 openpose/models 下面的文件一次性覆盖到位,跳过在线下载那一步。适合两类人:一类是刚搭好 OpenPose 环境、在模型下载这个黑匣子里翻过车的新手;另一类是要在内网或多台机器上批量部署、没法每台都走在线下载的运维。先搞清楚版本和目录结构再动手,能少踩一半坑。

2. 覆盖前先确认版本与目录结构:三套模型不能混用

2.1 OpenPose 版本决定模型目录:先确认你的代码用哪个 model_pose

OpenPose 1.7.x 系列默认的模型是 BODY_25,对应 models/pose/body_25/ 下的 pose_iter_584000.caffemodel 和 pose_deploy.prototxt。BODY_25 输出 25 个关键点,是目前做 openpose 骨架行为识别用得最多的模型;它的关键点覆盖到双脚各 4 个点,对步态分析和摔倒检测这类任务更友好。早期教程里大量出现的是 COCO 模型(18 点,models/pose/coco/)和 MPI 模型(16 点,models/pose/mpi/)。如果代码里写的是 --model_pose COCO,那就必须覆盖 coco 目录下的 pose_iter_440000.caffemodel;如果写的是 BODY_25,则需要 body_25 目录下的 pose_iter_584000.caffemodel。

为什么要先确认这一点?因为覆盖文件并不是“丢进去就行”,OpenPose 在启动时按目录名去找对应的 prototxt 和 caffemodel,目录名不对就报找不到。我一般会先翻一下项目里的启动脚本,或者直接在命令行里搜 model_pose 参数,确认当前项目默认加载哪一套,再决定覆盖范围。如果项目同时支持多种模型,那就把 body_25、coco、mpi 三套都覆盖完整,运行时按参数切换。

COCO 的 18 点模型相对轻量,在显存吃紧或者想跑更高帧率时比 BODY_25 实用。选哪个模型直接决定要覆盖哪一套文件,也决定后续 JSON 输出里关键点数组的长度,这一条往下看会反复用到。

2.2 models 目录完整布局:caffemodel 和 prototxt 要成对出现

OpenPose 的 models 目录不是把所有模型文件堆一起就能识别的,它按子目录找文件。完整布局长这样:

models/ ├── face/ │ ├── pose_deploy.prototxt │ └── pose_iter_116000.caffemodel ├── hand/ │ ├── hand_pose_left.caffemodel │ ├── hand_pose_left.prototxt │ ├── hand_pose_right.caffemodel │ └── hand_pose_right.prototxt └── pose/ ├── body_25/ │ ├── pose_deploy.prototxt │ └── pose_iter_584000.caffemodel ├── coco/ │ ├── pose_deploy_linevec.prototxt │ └── pose_iter_440000.caffemodel └── mpi/ ├── pose_deploy_linevec.prototxt └── pose_iter_160000.caffemodel

每个模型目录里必须同时存在 .caffemodel(网络权重)和 .prototxt(网络结构)。OpenPose 加载时先读 prototxt 解析网络层,再读 caffemodel 填充权重,缺一不可。覆盖时如果只拷贝体积大的 caffemodel,漏了 prototxt,加载照样失败。文件名也要严格对应:body_25 的 prototxt 叫 pose_deploy.prototxt,coco 和 mpi 的都叫 pose_deploy_linevec.prototxt,因为它们的网络结构不一致,命名就是按模型区分的。

hand 目录下的四个文件是左右手两个网络,加载手部关键点时左右手各用一套,文件里的 left/right 不能互换。face 目录相对独立,是 70 点模型。如果整套覆盖下去,磁盘占用会比只放 pose 模型多不少,提前留出空间。

2.3 prototxt 与 caffemodel 的对应关系:最容易混的文件组合

下面这张表是覆盖操作时最该对照的一张表,我贴在 models 目录旁边好几年了:

模型名模型目录权重文件结构文件关键点数
BODY_25models/pose/body_25/pose_iter_584000.caffemodelpose_deploy.prototxt25
COCOmodels/pose/coco/pose_iter_440000.caffemodelpose_deploy_linevec.prototxt18
MPImodels/pose/mpi/pose_iter_160000.caffemodelpose_deploy_linevec.prototxt16
手部models/hand/hand_pose_left/right.caffemodelhand_pose_left/right.prototxt21
面部models/face/pose_iter_116000.caffemodelpose_deploy.prototxt70

最容易混的不是目录,而是 prototxt。body_25 的 pose_deploy.prototxt 和 face 的 pose_deploy.prototxt 文件名相同,但一个在 pose/body_25 下,一个在 face/ 下,放在各自目录里没问题,一旦拷出来交叉使用就乱套。body_25 的 pose_iter_584000.caffemodel 也不能拿去配合 COCO 的 pose_deploy_linevec.prototxt,网络层尺寸对不上会直接崩。覆盖时按子目录整体操作,比单个文件挑着拷要安全得多。

2.4 文件校验与完整性核对:覆盖前记录原始状态

覆盖前我习惯先看一下当前目录里有什么,方便覆盖后核对。OpenPose 官方仓库里其实只带 prototxt,caffemodel 需要自己放进去,所以第一次打开 models 目录通常是缺一堆权重文件的。用 find 看一次:

cd /path/to/openpose find models -type f -name "*.caffemodel" -o -name "*.prototxt" | sort

这条命令会把所有模型相关文件列出来。如果输出里只有 prototxt,没有 caffemodel,说明这正是需要覆盖缺失的部分。官方安装流程里一般会执行 getModels.sh 去拉取这些文件,但很多环境的下行链路并不顺畅,某个大文件下到一半就卡住,脚本超时退出;内网机器上外部网络不可达时,连下载的机会都没有。覆盖型资源就是用来解决这种场景的:在能联网的机器上备好全套文件,传到内网后直接覆盖 models/,版本一致、目录一致,效果和在线下载没差别。

文件完整性方面,我一般用两个命令做双重确认。先看体积:

ls -la models/pose/body_25/pose_iter_584000.caffemodel

正常的权重文件应该是百 MB 级别,如果 ls 显示只有几 KB,基本能断定文件不完整,加载必失败。再用 md5sum 记录哈希:

md5sum models/pose/body_25/pose_iter_584000.caffemodel

md5sum 输出的哈希值记下来,后面排查“模型文件是不是坏了”时直接对比,不用重新下载。哈希校验在批量部署多台机器时尤其有用,我通常会写一个小脚本逐台比对,确保每台机器的模型文件一致。

2.5 安装前的检查脚本:30 秒确认环境状态

手动 find 看完之后,我一般再跑一个更直接的检查脚本。脚本逻辑很简单,把关键模型路径列出来,逐个判断文件是否存在,缺哪个就直接打印哪个:

#!/bin/bash # check_models.sh - 检查 OpenPose 模型目录是否完整 MODELS_DIR=${1:-./models} required_files=( "pose/body_25/pose_deploy.prototxt" "pose/body_25/pose_iter_584000.caffemodel" "pose/coco/pose_deploy_linevec.prototxt" "pose/coco/pose_iter_440000.caffemodel" "pose/mpi/pose_deploy_linevec.prototxt" "pose/mpi/pose_iter_160000.caffemodel" ) echo "检查目录: $MODELS_DIR" missing=0 for f in "${required_files[@]}"; do if [ ! -f "$MODELS_DIR/$f" ]; then echo "缺失: $f" missing=1 fi done if [ $missing -eq 0 ]; then echo "核心模型文件齐全" else echo "存在缺失文件,请覆盖后再运行" fi

脚本默认检查 ./models,也可以指定绝对路径:

bash check_models.sh /opt/openpose/models

这里只检查了三套 pose 核心模型,如果项目里用到手部和面部,把 hand 与 face 的关键路径按同一格式追加进去即可。脚本执行完,只看输出里有没有“缺失”字样,有就说明当前覆盖还没到位,先补齐再往下走。这个脚本本身不删除任何文件,反复执行没有副作用,可以当作环境自检的一部分保留下来。

3. 覆盖 models 目录的操作:解压、校验与路径配置

3.1 解压与覆盖:保持目录结构,一次到位

拿到 openpose-models 资源后,第一件事不是解压,而是先看压缩包内部结构:

tar -tzf openpose-models.tar.gz | head -20

这一步很关键。如果输出第一层是 models/...,直接解压到项目根目录即可;如果第一层是 openpose-models/...,那就要先解压再移动,否则会多套一层目录。我见过不少人把压缩包解压到项目目录后仍然报找不到模型,一看路径已经变成 openpose-models/models/pose/...,白白多了一层,OpenPose 自然找不到。

确认结构没问题后执行覆盖:

tar -xzf openpose-models.tar.gz -C /path/to/openpose

-C 指定解压目标目录。tar 会把包内的 models/ 直接合并进已有的 models/ 目录,同名的 prototxt 会被覆盖,不存在的 caffemodel 会新增,原有目录里其他文件不受影响。覆盖前记得先 df -h 看一下磁盘余量,全套模型覆盖到位后占用可能接近 1GB,很多小机器根分区余量不足,解压到一半写不进去,报的错看起来像压缩包坏了,实际是磁盘满了。

3.2 覆盖后的目录检查:确认每个文件落在正确位置

解压完,我习惯把第 2 章的检查脚本再跑一遍,确认没有遗漏:

bash check_models.sh /path/to/openpose/models

输出“核心模型文件齐全”才算过。手动看的话,重点确认几个容易放错的位置:pose_iter_584000.caffemodel 必须在 models/pose/body_25/ 下,pose_iter_440000.caffemodel 必须在 models/pose/coco/ 下。别把 BODY_25 的文件放到 coco 目录里,文件名对不上,加载时照样报找不到。

文件权限也是一个容易忽略的点。从 Windows 传过来的文件在 Linux 上经常丢权限位,虽然 caffemodel 不需要执行权限,但目录权限不对可能导致读取失败。统一刷一遍比较省心:

chmod -R 755 /path/to/openpose/models

chmod 之后再做一次校验,确认目录结构、文件权限都对,再进入启动阶段。

3.3 --model_folder 参数:运行时最容易写错的路径

OpenPose 找模型靠 --model_folder 参数,默认值是 ./models/。麻烦在于这个默认值以当前工作目录为基准,而不是以可执行文件所在目录为基准。很多人从 build/examples/openpose 目录直接运行 openpose.bin,结果它跑去 build/examples/openpose/models 找模型,当然找不到。我一般从项目根目录统一启动:

cd /path/to/openpose ./build/examples/openpose/openpose.bin \ --model_folder ./models/ \ --image examples/media/COCO_val2014_000000000192.jpg

如果一定要在别的目录运行,就用绝对路径:

./build/examples/openpose/openpose.bin \ --model_folder /path/to/openpose/models/ \ --image /path/to/openpose/examples/media/COCO_val2014_000000000192.jpg

还要注意 --model_pose 参数与模型目录的对应关系。OpenPose 1.7.x 默认 model_pose 是 BODY_25,如果只覆盖了 coco 目录的模型,运行时就显式加 --model_pose COCO,否则启动会去 body_25 目录找模型。启动参数与覆盖的文件范围必须保持一致,别混搭。有一种我称之为玄学的现象:路径写对了、文件也在,仍然报找不到模型,这种情况下多半是大小写问题,body_25、coco、mpi 这些目录名都是小写,不要自己改名。

3.4 多平台部署:Linux 与 Windows 的覆盖差异

OpenPose 在 Linux 和 Windows 下对 models 目录的读取逻辑一致,但覆盖方式有差异。Windows 上要确认覆盖的是哪个构建目录对应的 models,用 IDE 构建时,模型目录通常和可执行文件同级;如果从 Release 目录运行,models 也放在该目录附近,别把整个工程根目录的 models 和构建目录里的 models 搞混。启动命令里的路径写正斜杠更省事,避免反斜杠转义问题。

Linux 批量部署时,我不建议直接用 cp -r 从一台机器往另一台拷,因为拷贝过程可能拆掉软链接。模型文件在源机器上如果是指向其他位置的软链接,scp 或 cp -r 会把链接指向的内容复制成普通文件,文件本身没问题,但整体结构会和源端不一致。我习惯的做法是源端 tar czf 打包,目标端 tar xzf 解压,文件属性和链接关系一次性保持住。多台机器批量操作时,打包完再分发,比逐目录拷贝可靠得多。

3.5 覆盖后快速试跑:一张图验证加载

覆盖完、配好路径,我建议立刻做一次最小验证,而不是直接跑完整流程。最小验证用 OpenPose 自带的一张测试图:

cd /path/to/openpose ./build/examples/openpose/openpose.bin \ --model_folder ./models/ \ --model_pose BODY_25 \ --image examples/media/COCO_val2014_000000000192.jpg \ --write_json ./output/ \ --display 0

模型文件路径不对,这一步会直接报错;一切正常的话,会在 ./output/ 目录生成一个带关键点坐标的 JSON 文件,终端里能看到模型加载和推理耗时的日志。服务器上没有显示器时,--display 0 能避免弹出窗口;如果连渲染都不想走,可以再加 --render_pose 0,把可视化流程整个跳过,速度更快。这一步能过滤掉绝大多数“覆盖没生效”的问题。

4. 覆盖后的启动故障排查:现象、原因与解决

4.1 caffemodel 解析失败:文件损坏与磁盘空间不足

现象:启动后立刻报错,日志类似:

E0717 10:22:30.123456 12345 io.cpp:82] Read failed: 0 Check failed: proto.ParseFromString(file_content) Failed to parse NetParameter file: models/pose/body_25/pose_iter_584000.caffemodel

原因:caffemodel 是二进制 Protobuf 文件,解析失败通常意味着内容不完整。常见情况有三种:下载或拷贝过程中文件被截断;磁盘空间不足导致解压写入不完整;文件被文本方式传输过,内容早已变形。有些下载工具会把下载失败的页面存成同名文件,表面看文件存在,打开却是 HTML 文本。

解决:先 ls -la 看文件体积,百 MB 级别的文件只有几 MB 的话直接重新覆盖;再 md5sum 对比哈希。文件内容是否变成文本,可以用 file 命令看类型,正常权重文件输出是 data 或 Protobuf 相关字样,如果输出显示 ASCII text 或 HTML document,基本不用怀疑,覆盖错了。磁盘满就先清理空间再解压,解压时临时空间大约是模型占用的一倍以上,预留出来。

4.2 找不到模型文件:工作目录与路径大小写

现象:

Cannot find file: models/pose/body_25/pose_iter_584000.caffemodel

原因:报错信息里是相对路径,OpenPose 以当前工作目录为基准拼接 --model_folder 和内部固定路径。从 build/examples/openpose 目录运行,它就会去 build/examples/openpose/models/... 找;Windows 下还有可能覆盖错了 models 目录,模型放到了工程根目录,程序却去构建目录找。

解决:cd 到项目根目录再运行,或者把 --model_folder 写成绝对路径。路径大小写也是常见原因,body_25、coco、mpi 都是小写目录名,不要改成 Body25 或 COCO——Linux 区分大小写,OpenPose 内部按固定字符串拼接,目录名不能随意改。我自己就遇到过把目录改成 Body25 导致排查半小时的情况,从那以后路径一概不手改。

4.3 网络层不匹配:prototxt 与 caffemodel 交叉错配

现象:

Check failed: layer_id >= 0 Unknown layer type

或者加载到中途报形状对不上:

Check failed: blob_shape(1) == bottom_shape(1) (5 vs. 25)

原因:OpenPose 各模型的 prototxt 结构不同,body_25 的 pose_deploy.prototxt 与 coco/mpi 的 pose_deploy_linevec.prototxt 网络层数量不一致。只覆盖 caffemodel 不动 prototxt,或者把 BODY_25 的权重文件配给 COCO 的 prototxt,Caffe 解析到某一层时形状对不上就直接崩。

解决:严格按第 2 章的表格成对覆盖,要么整个子目录一起覆盖,要么不要动。覆盖后确认 body_25 目录下只有 pose_deploy.prototxt 加 pose_iter_584000.caffemodel 这一对,coco 目录下只有 pose_deploy_linevec.prototxt 加 pose_iter_440000.caffemodel 这一对。交叉错配的错最难查,因为报错发生在模型内部,从日志看不出来是文件混了,只能靠目录检查提前规避。

4.4 显存或内存不足:加载即崩与运行时中断

现象:

Check failed: error == cudaSuccess (2 vs. 0) out of memory

原因:BODY_25 模型默认输入分辨率较高,显存占用大。多人场景下中间特征图叠加,显存不够就会触发这个错误。CPU 跑的时候同理,内存不够一样会分配失败,而且模型加载本身还要额外吃一部分内存。

解决:启动参数里调低网络分辨率:

--net_resolution -1x368

从默认的 656x368 降到 -1x368 可以明显降低显存占用,代价是精度和关键点质量略有下降。GPU 实在不够时也可以关掉 GPU 跑 CPU 模式,速度会慢不少,一张图在普通桌面 CPU 上可能耗时几秒到十几秒。还有一种做法是加 --disable_multi_thread 降低线程竞争,低端 CPU 上能减少卡顿,但推理耗时不会质变。我一般先用小图验证加载正常,再上真实场景。

4.5 手部或面部模型缺失:--hand --face 参数引发的问题

现象:

Cannot find hand model, please download it

或者提示找不到 face 模型。

原因:OpenPose 默认只加载 pose 模型,手部和面部模型按需加载。很多人覆盖模型时只覆盖了 pose 目录,hand 和 face 目录都是空的。代码里一旦加了 --hand --face,程序就会去读 models/hand/ 和 models/face/ 下的文件,缺了就报错。

解决:如果只做全身骨架行为识别,启动参数里去掉 --hand --face 即可,手部模型缺失不影响全身关键点输出。如果流程确实需要手部或面部关键点,就把 hand/ 与 face/ 目录一并覆盖完整,覆盖后同样用 find 确认 hand_pose_left.caffemodel 和 hand_pose_right.caffemodel 都在。加载手部模型时左右手各占一份网络,缺一边都会报错。

4.6 覆盖后加载的仍是旧模型:缓存与进程占用

现象:明明覆盖了文件,重新运行时模型表现和覆盖前一模一样,加载日志也没有变化。

原因:Caffe 在部分版本里对模型文件会做内存映射,运行过程中替换文件会导致旧映射被进程继续使用;Python API 如果在同一个进程里反复初始化,模型文件首次加载后就被进程缓存了。共享存储或映射目录场景下,覆盖操作还可能只写到了缓存层。

解决:覆盖模型文件前先把 OpenPose 进程停掉,覆盖完再启动。用 Python API 调试时,每次更换模型文件后最好重启脚本或重启解释器,不要指望热加载。Linux 下可以用 lsof 查一下谁占用了模型文件:

lsof /path/to/openpose/models/pose/body_25/pose_iter_584000.caffemodel

有进程在读取时先停掉,再重新覆盖。这条排查思路在多人共用的服务器上尤其有用,有时候是别人起的进程占着模型文件,你覆盖了半天根本没生效。

5. 验证模型生效:一张测试图与 pose_keypoints 的 75 个值

5.1 命令行验证:看 JSON 输出里的关键点数组长度

覆盖完成后,我最常做的一件事就是跑一次带 --write_json 的命令,然后打开输出 JSON 看关键点数组的形状:

cd /path/to/openpose ./build/examples/openpose/openpose.bin \ --model_folder ./models/ \ --model_pose BODY_25 \ --image examples/media/COCO_val2014_000000000192.jpg \ --write_json ./output/ \ --display 0

运行成功的标志是终端输出模型加载和推理耗时信息,同时 ./output/ 下生成与输入图片同名的 JSON 文件。打开 JSON,重点看 people 数组下的 pose_keypoints_2d 字段。BODY_25 模型下这个字段长度是 75,也就是 25 个关键点乘以 3 个值(x、y、置信度)。如果看到的是 54,说明实际加载的是 COCO 18 点模型;48 则是 MPI 16 点模型。凭数组长度就能反向确认当前加载的是哪套模型,这个判断方法比其他方式都直接。

提示:解析 JSON 时按 OpenPose 官方的关键点顺序表去映射骨骼连接关系,鼻子、脖子、右肩……顺序是固定的,写代码前先对照顺序表,避免把关键点连错。

5.2 Python API 验证:打印 poseKeypoints 维度

走 Python API 的话,验证方式更直观,直接打印 datum.poseKeypoints 的 shape:

import sys import cv2 sys.path.append('./build/python') from openpose import pyopenpose as op params = dict() params["model_folder"] = "./models/" params["model_pose"] = "BODY_25" opWrapper = op.WrapperPython() opWrapper.configure(params) opWrapper.start() datum = op.Datum() image_path = "./examples/media/COCO_val2014_000000000192.jpg" datum.cvInputData = cv2.imread(image_path) opWrapper.emplaceAndPop([datum]) print(datum.poseKeypoints.shape)

参数说明:model_folder 指向 OpenPose 项目的 models 目录;model_pose 要与覆盖的模型保持一致。模型文件损坏时,emplaceAndPop 这一行会直接抛异常;一切正常时输出 shape 是 (1, 25, 3),表示检测到 1 个人、25 个关键点、每个关键点 3 个值。图像里有多个人时第一维就是人数,比如 (3, 25, 3)。从那以后我每次覆盖模型,都会强制走一遍这个最小验证:一张图、一次推理、看一眼 shape,确认模型真的在干活,而不是等到正式流程跑到一半才暴露问题。希望这篇笔记能帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询