资讯详情

端侧Pose后处理实战:从输出Tensor到人体关键点解码全解析

📅 2026/10/11 7:54:04 | 华诺云谱 👁 阅读
端侧Pose后处理实战:从输出Tensor到人体关键点解码全解析
1. 从一堆浮点数到看得懂的人Pose 后处理到底卡在哪如果你已经跑通了端侧模型推理拿到了输出 Tensor恭喜你最玄学的部分才刚刚开始。模型吐出来的东西本质上就是一堆形状为[1, C, H, W]或者[1, N, K]的浮点数它们既不是人也不是框更不是关键点。Pose 后处理要干的事就是把这堆数字翻译成人类能理解的语义这里有几个人、每个人在哪、他的肩膀和膝盖分别在哪。很多人第一次做 Pose 部署时会有一个误区觉得后处理就是写几行解码代码随便抄一份开源实现就行。但实际踩过坑的人都知道后处理才是端侧 Pose 落地里最容易翻车的一环——它直接决定了你的关键点抖不抖、框准不准、多人场景会不会串人、低算力设备上帧率能不能保住。同一份模型权重后处理写得糙和写得细最终效果能差出一个档次。这篇笔记面向的是已经了解端侧推理基本流程、能拿到输出 Tensor、但对接下来怎么办还比较模糊的开发者。我会把 Pose 后处理拆成几个真实存在的环节输出 Tensor 的典型布局长什么样、置信度与坐标是怎么编码的、人体框和关键点是怎么从同一份输出里解出来的、多人场景下怎么做匹配、以及端侧特有的量化反解和性能取舍。全程用从业者的视角讲为什么这么做而不是只丢一段代码让你抄。需要先说明一点不同模型无论是自研的还是公开的输出格式差异很大下面讲的是主流自顶向下和自底向上两类 Pose 方案里最常见的编码方式具体到你的模型一定要以它的输出定义为准。我会在关键处标注这里要对照你的模型文档确认。2. 先看懂输出 Tensor 的布局别急着写解码2.1 两种主流输出形态热力图 vs 直接回归Pose 模型的输出粗略分两大类。第一类是**热力图Heatmap形态输出通常是[1, K, H, W]K 是关键点数量常见 17 或 21H、W 是特征图的高宽。每个通道代表一个关键点通道里数值最大的那个位置就是模型认为该关键点最可能在的地方。第二类是直接回归Regression**形态输出是[1, N, K*2]或[1, N, K*3]直接给出每个关键点的坐标或者坐标加置信度。热力图的好处是空间精度高、对遮挡鲁棒缺点是后处理要做 argmax 和亚像素修正计算量不小直接回归的好处是后处理简单、速度快缺点是精度上限通常不如热力图尤其是小目标和高分辨率场景。端侧选哪种取决于你的算力预算和精度要求。我个人的经验是中低端设备上如果模型本身已经做了轻量化直接回归的后处理开销更可控如果追求关键点精度且设备有 NPU 加速热力图方案更值得投入。拿到输出后第一件事不是写代码而是打印 shape 和数值范围。我见过太多人对着[1, 56, 48, 64]这种 shape 发懵其实 56 可能就是 17 个关键点乘以某个系数或者包含了框的回归量。把 shape 打印出来再对照模型导出时的输出节点定义能省掉大量瞎猜的时间。2.2 通道顺序与坐标系两个最容易搞反的地方通道顺序上常见的有[N, C, H, W]NCHW和[N, H, W, C]NHWC。端侧推理框架导出时经常会把 NCHW 转成 NHWC 来适配某些加速器如果你按 NCHW 去索引结果就是关键点全部错位、画出来像抽象画。判断方法很简单看哪个维度等于关键点数量 K。如果某个维度正好是 17 或 21那它大概率就是通道维。坐标系是另一个重灾区。热力图的坐标是相对于特征图尺寸的要映射回原图需要乘以一个缩放系数通常是原图宽 / 特征图宽。但这里有个坑很多模型的输入是 letterbox 处理过的也就是保持长宽比缩放后补边。这种情况下你不仅要缩放还要减去补边的偏移量否则关键点会整体偏移。我踩过这个坑当时关键点总是往右下角偏排查了半天才发现是 letterbox 的 padding 没减掉。提示在写任何解码逻辑之前先用一张只有一个人的清晰图片把关键点画在原图上。如果点整体偏移、整体缩放错误、或者左右镜像基本就是坐标系或通道顺序的问题而不是模型精度问题。2.3 量化输出的反解int8 到 float 的那一步端侧模型很多是 int8 量化的输出 Tensor 里存的是整数需要反量化回浮点。反量化公式通常是real (q - zero_point) * scale其中 scale 和 zero_point 来自量化参数。这一步看起来简单但有两个细节容易忽略。第一scale 和 zero_point 是逐通道还是逐张量。逐通道量化时每个输出通道有自己的 scale如果你用统一的 scale 去反解数值会整体失真热力图的峰值位置可能就偏了。第二反量化的时机。有些框架在输出节点已经帮你反量化好了你拿到的是 float有些则要自己反解。判断方法是看输出 dtype如果是 int8 或 uint8那基本要自己处理。我一般会在后处理入口处加一段断言检查输出 dtype 和数值范围。如果 dtype 是 float 但数值全在 0 到 255 之间那很可能是假 float实际还是量化值需要按量化参数处理。这种问题不报错但结果就是不对非常隐蔽。3. 置信度与坐标解码热力图峰值怎么变成精确坐标3.1 argmax 只是起点亚像素修正才是精度关键热力图解码的第一步是找峰值也就是对每个关键点通道做 argmax得到特征图上的整数坐标。但整数坐标的精度受限于特征图分辨率比如特征图是 48x64那坐标精度就是原图尺寸除以 48 或 64可能有好几个像素的误差。对于手指、眼睛这种小关键点这个误差是不能接受的。所以主流做法是亚像素修正最常见的是对峰值点及其邻域做加权平均或者用二次函数拟合峰值附近的分布。简单说就是取峰值点周围 3x3 或 5x5 的区域用数值大小作为权重算出加权中心。这样能把坐标精度提升到亚像素级别。我实测下来加了亚像素修正后关键点的抖动明显减小尤其是视频连续帧上视觉稳定性提升很大。还有一种做法是偏移量回归offset regression模型额外输出一个偏移通道直接预测峰值点到真实位置的偏移。这种方式精度更高但需要模型支持后处理时把偏移量加到整数坐标上即可。如果你的模型有 offset 输出一定要用上别浪费。3.2 置信度阈值不是越低越好也不是越高越好每个关键点都有一个置信度通常就是热力图峰值的大小或者回归分支直接输出的分数。置信度阈值决定了哪些关键点被保留。阈值设太低噪声点会被当成关键点画出来一堆乱七八糟的点设太高遮挡或模糊的关键点会被丢掉骨架断断续续。我的经验是阈值要分关键点类型设置。比如鼻子、眼睛这种通常比较清晰的关键点阈值可以高一点0.5 左右手腕、脚踝这种容易遮挡的阈值可以低一点0.3 左右。统一阈值在复杂场景下很难兼顾。另外如果做的是多人 Pose还要考虑整体置信度也就是一个人所有关键点置信度的平均值或最小值用来过滤掉误检的人。注意置信度阈值和后面的 NMS 阈值是两回事不要混在一起调。置信度管的是这个点/这个人可不可信NMS 管的是这个框和那个框是不是同一个人。3.3 从特征图坐标回到原图缩放、padding、翻转一个都不能少前面提到过 letterbox 的坑这里展开说完整流程。假设模型输入是 256x256原图是 640x480letterbox 后缩放系数是256/640 0.4缩放后高度是480*0.4 192上下各补(256-192)/2 32的边。那么从特征图坐标回到原图的步骤是特征图坐标乘以特征图到模型输入的缩放比得到模型输入坐标系下的坐标减去 padding 偏移这里是 32除以缩放系数 0.4得到原图坐标。如果模型还做了水平翻转增强有些训练时会做推理时一般不做但有些导出会带那还要做一次镜像。这些步骤顺序不能乱乱一步结果就偏。我建议把这一整套变换写成一个函数输入是特征图坐标和原图尺寸输出是原图坐标这样复用起来不容易出错。4. 人体框从哪来检测框与关键点的两种耦合方式4.1 自顶向下先有人体框再在框里找关键点自顶向下Top-down方案的流程是先用一个人体检测器比如轻量 YOLO 或 SSD检测出所有人的人体框然后对每个框裁剪出区域送进 Pose 模型预测关键点。这种方案的关键点精度通常更高因为每个框里的分辨率更集中但缺点是检测器和 Pose 模型是两套网络端侧总开销更大而且检测框的质量直接影响关键点质量。后处理上自顶向下要处理两件事一是检测框的 NMS去掉重叠的框二是框的扩展因为检测框通常只框到人体主体手腕、脚踝可能露在框外直接裁剪会丢关键点。常见做法是把框按比例向外扩展 10% 到 20%再裁剪。扩展比例需要根据你的检测器风格调框紧的检测器要多扩一点。4.2 自底向上先找所有关键点再拼成人自底向上Bottom-up方案是先检测出图中所有人的所有关键点然后通过关联策略把属于同一个人的关键点拼起来。这种方案的好处是一次推理搞定所有人速度与人数无关适合多人场景缺点是后处理的关联逻辑复杂人一多容易串。关联策略里最经典的是部分亲和场PAF模型额外输出一组向量场表示关键点之间的连接方向。后处理时沿着两个人候选关键点之间的连线采样 PAF 向量如果方向一致度高就认为它们属于同一个人。这套逻辑实现起来不复杂但采样点数量和积分方式对结果影响很大采样太少会误连采样太多会慢。我一般用 10 个采样点端侧上速度和精度比较平衡。4.3 两种方案在端侧的取舍别只看精度很多人一上来就选自顶向下因为精度高。但在端侧总延迟才是硬指标。自顶向下要跑两次网络检测器虽然轻但加上 Pose 模型总开销可能是自底向上的 1.5 到 2 倍。如果设备算力有限或者场景里人数不多比如 1 到 3 人自底向上反而更划算。我的建议是先明确你的场景人数分布。如果绝大多数时候只有 1 个人自顶向下配合一个极轻的检测器完全可行如果经常有多人且算力紧张自底向上更合适。另外自顶向下还有一个隐藏成本框的数量决定了 Pose 模型的调用次数人数多的时候延迟线性增长这点在端侧要特别小心。5. 多人场景的匹配与去重NMS 和关联策略的实操细节5.1 人体框 NMSIoU 阈值怎么定自顶向下方案里检测器输出的框需要做 NMS。IoU 阈值设太低同一个人会被多个框覆盖Pose 模型重复计算设太高相邻的人可能被合并。常见阈值在 0.45 到 0.6 之间。但端侧 Pose 场景有个特殊性人体框通常比较瘦长两个人并排站时 IoU 可能不高但框有重叠。这时候纯 IoU 的 NMS 可能不够可以考虑用DIoU或者加入中心点距离的惩罚减少误合并。我踩过一个坑在拥挤场景下两个挨得很近的人检测框 IoU 只有 0.3NMS 没合并结果 Pose 模型对两个框都预测出了相似的关键点画出来两个人重叠。后来加了基于关键点相似度的二次去重也就是如果两个框预测出的关键点平均距离很近就认为是同一个人去掉一个。这个逻辑不复杂但在拥挤场景下很有效。5.2 关键点关联PAF 积分与贪心匹配自底向上的关联PAF 积分是核心。具体做法是对于每一对可能相连的关键点比如左肩和左肘在它们连线上等距采样若干点取这些点上的 PAF 向量和连线方向做点积再求平均。平均分高于阈值的认为这对关键点可以连接。得到所有候选连接后用贪心匹配把关键点拼成骨架每次选分数最高的连接把两个关键点归到同一个人直到所有连接处理完。这里有个细节一个人可能有多个候选连接指向同一个关键点贪心匹配要保证一个关键点只属于一个人。实现时用一个标记数组记录已分配的关键点即可。5.3 骨架完整性校验过滤半个人不管是哪种方案最后都要做一次骨架完整性校验。如果一个人只检测到 2 到 3 个关键点画出来就是几个孤立的点没有意义。常见做法是要求至少检测到一定数量的关键点比如 5 个或者要求核心关键点肩、髋至少有一组存在。这个阈值要根据你的应用调如果是健身计数可能要求四肢关键点齐全如果是人群密度估计要求可以低一点。提示骨架完整性校验的阈值不要写死最好做成可配置参数。不同场景对有效人体的定义不一样写死了后期改起来很麻烦。6. 端侧特有的性能与精度取舍后处理也能成为瓶颈6.1 后处理的耗时分布别只盯着模型推理很多人优化端侧 Pose只关注模型推理时间忽略了后处理。实际上热力图解码 亚像素修正 NMS 关联这一套下来在中低端 CPU 上可能占到总耗时的 30% 到 50%。尤其是热力图方案argmax 和邻域加权是逐像素操作特征图一大就很慢。优化手段有几个一是降低特征图分辨率但会损失精度二是用 SIMD 或 NEON 指令加速这个需要一些底层优化经验三是把后处理也放到 NPU 或 GPU 上但很多端侧框架对自定义后处理算子支持有限。我的经验是优先优化热力图解码部分因为它是纯计算密集且容易并行化的用多线程或向量化指令收益最明显。6.2 量化对后处理的影响阈值和坐标都要重新标定int8 量化不仅影响模型推理也影响后处理。量化后的热力图峰值可能变平亚像素修正的加权中心会偏移置信度分布也会变化原来在 float 模型上调好的阈值换到 int8 上可能就不适用了。所以量化后一定要重新标定阈值不能直接沿用 float 模型的参数。我的做法是准备一小批代表性图片分别用 float 模型和 int8 模型跑一遍对比关键点坐标和置信度的分布然后调整阈值和亚像素修正的邻域大小。这个过程不复杂但能避免很多量化后效果变差的抱怨。6.3 帧间平滑让关键点不抖的实用技巧端侧 Pose 很多是视频流场景逐帧独立预测会导致关键点抖动。简单的帧间平滑就能显著提升视觉体验。最常用的是指数移动平均EMA当前帧的关键点坐标和上一帧做加权平均权重比如 0.7 当前帧 0.3 上一帧。这样既保留了响应速度又抑制了抖动。但 EMA 有个问题快速运动时会有拖影。解决方法是加入运动自适应如果当前帧和上一帧的关键点距离超过阈值就降低上一帧的权重甚至直接用当前帧。这个逻辑几行代码就能实现效果提升很明显。我在实际项目里加了运动自适应 EMA 后用户反馈看起来稳多了。7. 一套可复现的后处理流程与调试心得7.1 从 Tensor 到可视化完整链路拆解把前面的内容串起来一套完整的 Pose 后处理链路大致是读取输出 Tensor确认 shape、dtype、通道顺序反量化如果是量化模型得到 float 数值热力图解码逐关键点通道 argmax得到峰值坐标和置信度亚像素修正对峰值邻域加权得到精确坐标坐标变换从特征图坐标映射回原图坐标处理 letterbox 和翻转置信度过滤按关键点类型过滤低置信度点人体框处理自顶向下NMS、框扩展、裁剪关键点关联自底向上PAF 积分、贪心匹配骨架完整性校验过滤无效人体帧间平滑EMA 加运动自适应。每一步都可以单独调试。我的习惯是先把第 3 到第 5 步调通用单张图片确认关键点位置正确再往上加关联和平滑。这样出问题时容易定位不会一堆逻辑混在一起。7.2 调试工具可视化比打印日志管用后处理调试可视化是最有效的工具。把关键点画在原图上用不同颜色区分不同的人置信度低的点画小一点或半透明。这样一眼就能看出是坐标偏了、还是关联错了、还是阈值不对。打印日志只能看到数值很难直观判断。我一般会写一个简单的可视化脚本输入是原图和输出 Tensor输出是画好骨架的图片。这个脚本在调试阶段反复用比任何日志都管用。另外保存中间结果也很重要比如把热力图峰值位置单独画出来和最终关键点对比能快速判断是解码问题还是变换问题。7.3 几个反复踩过的坑与对应解法最后分享几个我在端侧 Pose 后处理上反复踩过的坑以及对应的解法关键点整体偏移九成是 letterbox 的 padding 没处理或者缩放系数用反了。解法是写一个独立的坐标变换函数单独测试。左右关键点镜像模型输出的关键点顺序和你的映射表不一致或者做了翻转没翻回来。解法是对照模型文档确认关键点顺序翻转时同步交换左右关键点索引。多人串人PAF 采样点太少或阈值太低导致不同人的关键点被连在一起。解法是增加采样点、提高关联阈值或者加入基于人体框的二次校验。量化后精度骤降阈值没重新标定或者反量化参数用错。解法是用代表性数据重新标定并检查逐通道 scale 是否正确应用。帧率不达标后处理成了瓶颈尤其是热力图解码。解法是优化解码循环、用多线程或者降低特征图分辨率。这些坑看起来都是小问题但在实际项目里每一个都可能卡你半天。把后处理当成一个独立的工程模块来对待写清楚输入输出、做好可视化、留好可配置参数后面维护起来会轻松很多。Pose 后处理不是什么高深算法但它考验的是你对细节的把握和对端侧约束的理解这两点恰恰是端侧 AI 落地最值钱的能力。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑