ARTICLE DETAIL

资讯详情

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

人体姿态估计选型实战:OpenPose与HRNet对比及部署避坑

人体姿态估计选型实战:OpenPose与HRNet对比及部署避坑 人体姿态估计这个方向我前后折腾了大概小半年从最早只会调OpenPose的Demo到后来自己拿HRNet在私有数据上从头训一遍中间踩的坑说出来能写一本书。很多人一上来就纠结到底用哪个模型其实这个问题问早了真正该先想清楚的是你的场景里人有多少、遮挡严不严重、要不要实时、部署端算力够不够。这四个问题想明白了模型选型基本就是顺水推舟的事。这一篇我把自己对OpenPose和HRNet这两条技术路线的理解、实操细节和避坑经验完整梳理一遍从关键点的定义一直讲到部署落地尽量把每一步为什么这么做讲透。不管你是刚接触人体姿态估计的新手还是已经跑过几个Demo但精度总上不去的老手应该都能从里面找到能直接抄作业的东西。1. 人体姿态估计要解决的核心问题与输出形式1.1 关键点到底是什么为什么是17个而不是别的数字人体姿态估计Human Pose Estimation干的事情本质是把一张图里人的身体结构用一组预定义的关键点坐标给它钉出来。你可以把它理解为给人体画一副火柴人骨架先确定关节在哪再把关节按生理结构连成线。听起来简单但关节这个概念本身就有歧义——肩关节的精确位置是按锁骨外端算还是按肱骨头算手腕是取掌根还是取桡骨茎突这些定义不同标注出来的真值就完全不同。所以业界干脆约定俗成用固定的一套点集来统一标准。最主流的是COCO的17点格式鼻子、左右眼、左右耳、左右肩、左右肘、左右腕、左右髋、左右膝、左右踝加上一个鼻子作为头部中心。MPII用的是16点多了胸骨和骨盆中心点头部的点也换成了头顶和下巴。CrowdPose为了应对拥挤场景用了14点砍掉了一些脸部细节点。我第一次做标注转换的时候没注意这个差异直接把MPII的真值喂给按COCO训练的模型mAP掉了一大截排查了半天才发现是点序对不上。这里有个很实际的建议在项目一开始就把关键点定义和顺序固化成一份文档所有数据标注、模型训练、后处理都引用同一份定义。我见过太多团队因为标注同学和算法同学对右肩的理解差了一个像素的语义导致模型怎么训都上不去。人脸的点、手部的点这些扩展点集比如OpenPose的135点全身版更要在项目初期就决定要不要不然中途加会推翻整个数据管线。1.2 自顶向下、自底向上、单阶段三条路线的本质区别多人姿态估计的难点在于图里有好几个人你怎么知道哪些关节属于同一个人解决这个归属问题衍生出了三条截然不同的技术路线。自顶向下Top-Down先用人检框把人一个个框出来再对每个框单独做单人姿态估计。HRNet、SimpleBaseline都是这条路线。它的优点是精度高因为每个框里的人尺度相对统一网络只需要专注关节定位缺点严重依赖检测器检测漏了人就全丢了而且人数越多耗时线性增长。我实测过一张图20个人自顶向下比自底向上慢三倍不止。自底向上Bottom-Up反过来先把全图所有人的所有关节都检测出来再想办法把关节分组归属到每个人。OpenPose是这条路的开山之作用Part Affinity FieldsPAF解决分组问题。它的优点是推理时间和人数无关人越多越划算适合密集人群缺点是分组容易出错两个人挨得近的时候肢体容易连错。单阶段Single-Stage是近几年的融合思路把检测和姿态统一在一个网络里端到端出结果代表是CenterNet姿态分支、SPM等。它在速度和精度之间找平衡但调参复杂度高工业落地还不太成熟。我一般这么选遮挡少、人数少、要精度选自顶向下人数多、要实时、算力有限选自底向上。这个判断后面还会展开。1.3 评价指标OKS、PCK、AP别被论文里的数字忽悠模型好不好得有个统一的尺子。姿态估计最核心的指标是OKSObject Keypoint Similarity它借鉴了目标检测里IoU的思想但算的是关键点的距离相似度OKS Σ[exp(-d_i² / (2·s²·k_i²)) · δ(v_i0)] / Σδ(v_i0)其中d_i是预测点和真值点的欧氏距离s是目标尺度一般取检测框面积的平方根k_i是每个关键点特有的衰减常数COCO给每个点都定义了一个值比如鼻子是0.026髋关节是0.107——因为髋关节标注本身就比鼻子模糊所以要宽容一点v_i是可见性标志。δ是指示函数只统计真值里存在的点。基于OKS再算APAverage Precision设定一系列OKS阈值0.5到0.95步长0.05每个阈值下计算召回率-精度曲线下的面积取平均。这就是常说的AP^0.95也是COCO官方主指标。PCKPercentage of Correct Keypoints更简单粗暴预测点落在真值某个阈值距离内的比例阈值通常取头部长度的百分比。PCK在小数据集上还有用但它对尺度不敏感跨数据集比较不可靠现在论文基本都用OKS系。一个坑要提醒不同代码库对OKS的具体实现细节有差异比如s到底取bbox面积还是面积开根号、可见点怎么过滤会导致同一个模型复现出来的AP差1到2个点。我对比过mmpose和HRNet官方仓库的实现就是这两个细节不同。所以复现论文结果之前先确认指标实现和原论文一致别自己辛苦训完发现是对不齐口径的锅。2. OpenPose的PAF机制自底向上为什么能work2.1 双分支网络置信度图和向量场各管什么OpenPose的网络结构是这个领域最经典的设计之一我第一次看论文的时候觉得思路特别巧妙。它基于VGG-19的前10层做特征提取然后分叉成两个平行的分支上面一支输出置信度图Confidence Map记作S下面一支输出Part Affinity FieldsPAF记作L。置信度图S负责关节在哪它输出J个通道J是关键点数量每个通道是一张热力图图上响应值最高的位置就是某个关节的坐标。这部分和单人的热力图方法没区别。PAF才是OpenPose的灵魂负责这个关节和那个关节属于同一个人。它是一个2×C通道的向量场C是肢体数量每个像素上存一个二维向量表示该像素到从某关节指向相邻关节的方向。比如前臂这条肢体左肘到左腕之间的区域就会布满指向腕部的向量。这样任意两个相邻关节连线上的向量如果方向一致、连贯它们大概率属于同一个人的同一条肢体。这两支在一个多阶段网络里反复迭代第t阶段的输入是上一阶段的特征图加原图特征逐步refine。损失函数就是两支的L2损失加权求和。这么设计的原因是姿态的局部信息和高层语义需要反复交互一步到位容易崩。2.2 为什么用PAF而不是直接回归坐标或分割你可能会问分组问题为什么不干脆用分割的思路做还真有人这么试过这种做法叫Associative Embedding给每个关节加上一致性标签。但这类分组方法的致命弱点是人体交叉、遮挡频繁的场景下标签传播容易混乱。PAF的高明之处在于它是基于肢体这一分数概念的、用点积几何规则来分组。论文里给出的匹配权重是E ∫∫ L_c(p(u)) · (d_j2 - d_j1) / ||d_j2 - d_j1||_2 du这里的物理意义很直白沿一条候选肢体方向把沿路所有像素的PAF向量投影到这条肢体的方向上积分起来。投影值越大说明该区域的手里的所有PAF方向越统一指向同一个身体的这条肢体。这个 可积分、可解析求解 的特性让分组变成了一个线性的二部图匹配问题用匈牙利算法或者贪心就能搞定代价极小。我拿两版做过对比同样的输入PAF分组在10到30人、身体互相遮挡的网络配置场景下副关节错连率明显低于纯嵌入的方法。这段实测下来的心得是肢体这一层语义比关节那一层更稳定因为单关节点容易被背景或同类关节误导但一整条肢体方向的一致性很难骗过去。2.3 贪心匹配的实现细节与二分图求解论文里最正统的做法是把所有候选连接构建成一个二维相似度矩阵然后用匈牙利算法求最大权匹配。匈牙利算法保证全局最优但复杂度是O(n³)人一多就慢。工业实现里普遍用贪心匹配把所有候选连接按得分排序从高到低依次取只要两个端点还没被占用就接受这个连接。贪心不保证全局最优但速度快几个数量级而且实测精度损失很小。我测过十几个人的场景贪心和匈牙利算法出来的结果几乎一样但延迟后者是前者的好几倍。有个细节很多人忽略匹配时要考虑肢体的相对位置关系不能只看PAF积分。比如右肘到右腕的候选如果连出来的方向和人体解剖学方向明显反常比如腕比肘还靠上很多应该降权。我在后处理里加了一个简单的位置先验过滤错连率能再降一些。2.4 跑通OpenPose的实操配置与常见报错OpenPose官方用的是Caffe实现编译那关就劝退了不少人。如果你的环境装不上Caffe我建议直接上两个替代方案一个是CMU的Caffe实现加预编译包一个是基于PyTorch的复现版比如OpenPose的PyTorch重写有很多社区版本。我实测PyTorch版推理速度不比Caffe慢太多但部署和调试友好得多。跑通的关键配置项就那么几个--net_resolution控制输入分辨率是速度和精度的直接权衡--num_gpu和多GPU推理--scale_number做多尺度测试能提升小目标精度但更慢。下面是我常用的命令行结构./build/examples/openpose/openpose.bin \ --image_dir ./images \ --write_json ./output/json \ --write_images ./output/vis \ --net_resolution 656x368 \ --scale_number 4 \ --scale_gap 0.25 \ --number_people_max 10net_resolution用16的倍数656x368是速度优先的配置追求精度可以调到 1312x736但显存和耗时直接翻四倍。scale_number配合scale_gap做多尺度金字塔输入对远处小目标尤其有用我在监控场景实测能提2到3个点的AP。常见报错里显存溢出最典型解决思路是调小net_resolution或加--num_gpu 0切CPU慢到不能用。还有一类是CUDA和cuDNN版本不匹配这个没有技巧严格按官方README的版本组合来。另有一个隐蔽的坑输出JSON里的点坐标是归一化到原图尺寸的但如果你做了resize预处理没同步还原坐标会整体偏移我在这上面浪费过整整一个下午。3. HRNet的高分辨率保持精度是怎么堆出来的3.1 高分辨率特征为什么会被下采样毁掉自顶向下的方法里HRNet是我最推荐的一个因为它把一个根本性的矛盾解决了。传统网络ResNet、VGG都是高分辨率进、低分辨率出的串联结构一开始特征图大、语义弱经过不断下采样特征图变小、语义变强。到了最后网络只保留了几十乘几十的低分辨率特征再上采样回去做关键点预测。问题就出在这关键点定位是需要空间精度的任务而低分辨率特征再上采样丢失的细节是补不回来的。你想想一个32×32的特征图上采样到256×256每个像素注定只能靠插值糊出来关节能定位到像素级才怪。这就是为什么ResNet类backbone在姿态估计上精度总有天花板。HRNet的做法是全程保留一条高分辨率支路。它从最高分辨率开始一边下采样开出新支路一边让所有支路并行存在然后在每个stage做反复的跨分辨率信息交换。高分辨率支路负责空间细节低分辨率支路负责语义两者通过融合取长补短。最终预测用的是那条高分辨率支路所以定位精度天然就高。我做过消融同样的训练数据、同样的训练时长HRNet比ResNet-50加反卷积头高出大概3到4个点的AP这差距在关键点上肉眼可见。3.2 多分辨率并行与反复交互的实现逻辑HRNet的结构拆开看其实很规整。它有四个stage每个stage由若干个基本模块BasicBlock或Bottleneck堆叠。以HRNet-W32为例第一路保持1/4原图分辨率、32通道第二路1/8分辨率、64通道往下依次翻倍。每到一个transition就从已有的每一路再下采样开出一条新的、通道翻倍、分辨率减半的支路。关键是融合fusion操作对每一个分辨率支路要接收来自其他所有支路的特征。低分辨率支路的信息通过上采样传过来高分辨率支路的信息通过带步长的下采样传过去全部对齐到目标分辨率后逐元素相加。这个操作在每个stage结束前都要做一遍所以信息在不同尺度之间来回流动低层细节和高层语义不断校准。我第一次实现这个融合的时候上采样用了最近邻结果发现双线性插值在关键点任务上更平滑热力图响应更集中最终AP略高。这种细节论文里不会写但实测有区别。另外跨支路融合时用的是逐元素相加不是concat这省了不少显存也避免了参数膨胀。3.3 热力图编解码从坐标到高斯再从高斯到坐标HRNet输出的还是热力图所以坐标和热力图的互相转换是绕不开的环节。标准做法有两种一种是直接回归归一化坐标Coordinate Classification/Regression一种是预测高斯热力图然后取峰值Heatmap-based。HRNet走的是后者。生成真值热力图的时候对每个关节先量化为整数坐标然后以该点为中心生成一个二维高斯分布标准差和人体尺度相关。常见的做法是固定sigma或者和bbox大小挂钩。我用下来固定sigma在COCO单类场景够用但跨尺度场景一个场景里既有远景小人又有近景大人必须用尺度自适应sigma否则小人的热力图峰值会糊到大人的三分之一都不到训练时小目标基本学不动。从热力图还原坐标最朴素的是取argmax。但argmax只有整数精度实测比取加权质心低0.5到1个AP。所以正规做法是找到峰值点后在峰值邻域取一小块用log函数近似原高斯做二次曲面拟合求亚像素极值x x0 0.25 * (H[x01] - H[x0-1]) / (2*H[x0] - H[x0-1] - H[x01])这个公式一行就能写但精度提升明显。很多人训完模型发现AP卡在某条线上上不去十有八九就是解码只用了argmax。3.4 训练配置与数据增强精度的另一半网络结构只决定上限训练配置才决定你能摸到多高。HRNet的官方训练配置里几个点我建议原封不动照抄别瞎改。优化器用Adam初始学习率1e-3在epoch 170和200各降一次乘以0.1总epoch 210。batch size给了32单卡跑不下就用梯度累积凑。数据增强主打half body随机裁一半身体、随机旋转±30度、随机缩放±25%、翻转。这里的half body是关键它逼着网络学会用局部信息推断整体对遮挡场景鲁棒性提升巨大。翻转增强有个隐藏坑左右翻转后关键点的索引要重新映射。COCO格式里左肩和右肩是索引5和6翻转后得互换否则网络学到的左右是反的。我见过有人忘了这步结果模型对左右手永远分不清AP^0.5还行但AP^0.95惨不忍睹。还有训练时长姿态估计的模型收敛比目标检测慢210个epoch不是随便定的。我早期图快只训了60个epochAP比官方报告低了快5个点后来补训才补回来。如果你的数据量小用COCO预训练权重微调是明智选择通常30到50个epoch就能收敛。3.5 推理后处理的三个细节优化模型跑通了不代表结果能用后处理里的细节直接决定线上体验。我总结了三个必做的事。第一个是多尺度测试multi-scale testing把输入缩放到几个不同尺寸分别预测热力图加权平均。这招在HRNet上提点很稳定通常1到2个AP代价是推理时间乘以尺度数。线上如果延迟敏感可以在验证阶段用它确认模型上限。第二个是热力图平均的两阶段翻转先原图预测再左右翻转预测把翻转的预测翻转回来和原预测平均。这个比单纯翻转训练更有用能抹平翻转引入的左右偏差。第三个是人体框和关键点的一致性校验如果某个关键点预测落在人体框外很远的地方多半是错的直接置为不可见。我加了这条规则之后可视化结果干净了不少那些飘到画面角落的乱点是评分最容易被扣分的。4. 数据集与标注最脏最累但最不能省的一环4.1 COCO、MPII、CrowdPose的选型与差异公开数据集选哪个取决于你的任务形态。COCO Keypoints是目前最通用的基准17点、超过20万张图、覆盖各种日常场景几乎所有论文都拿它做对比预训练权重也最容易找。MPII是更早的基准16点单人标注为主现在主要用来做早期方法对比。CrowdPose专门针对拥挤人群14点图里全是人挤人的场景自底向上方法在它上面才见真章。选数据集还要看你的目标场景像谁。做健身动作识别MPII的瑜伽/体操类图像更贴近做公共场所人流分析CrowdPose更有代表性做通用场景直接COCO。我一般建议先用COCO预训练打底再用自己场景的数据微调两全其美。有个统计值得记一下COCO关键点标注里大约有相当一部分实例存在关节不可见被遮挡或在画面外这些点的v标志位是0OKS计算要排除。这提醒我们评估自己模型时一定要区分可见点AP和全点AP线上场景里遮挡永远是常态。4.2 常见人体动作与遮挡、截断的处理真实场景里最难的三类情况遮挡occlusion、截断truncation、极端姿态extreme pose。遮挡分自遮挡自己挡住自己和他人遮挡截断是人在画面边缘只露出半截极端姿态是瑜伽、体操那种大角度扭转。处理这些没有银弹但有套组合拳训练时用Cutout、随机遮挡增强模拟遮挡用half body增强模拟截断用大角度旋转增强模拟极端姿态。同时要在损失函数里对不可见点降权甚至忽略否则网络会去拟合那些根本不存在的点白费力气还学歪。我还发现一个规律数据集里站立行走的常规姿态占绝大多数跑步、跳跃这类动态姿态样本很少。如果业务就是运动分析必须自己补采这类数据光靠公开数据集的自然分布模型会偏。这个问题在关键词常见人体动作里其实有暗示做姿态估计绕不开对动作分布的先验理解。4.3 标注格式转换JSON与COCO格式互转的坑工程里最常见的操作是把各种标注转成COCO格式因为大多数开源训练框架默认吃COCO。转的时候有三个坑必须防。一是点索引映射。不同数据集的点顺序完全不同必须写一张映射表逐点手动核对。我一般会写个小脚本随机抽样可视化几个样本叠加在原图上肉眼确认连线是对的。二是可见性标志。COCO的v有三档0不可见、1被遮挡但可推断、2完全可见。很多转换脚本偷懒全填2结果训练时把遮挡点当真值硬训模型学了错误监督。正确做法是按实际情况填。三是bbox的确定。关键点转COCO需要提供人体框自底向上方法可以没有框但自顶向下需要。框一般取所有可见点的外接矩形然后按比例外扩。外扩比例这个参数我试过扩1.25倍是比较平衡的选择扩太小会切掉关节扩太大背景干扰多。下面是一段把自定义JSON转COCO格式的骨架代码我日常都用类似的模板import json # 点序映射把你的标注点序映射到COCO 17点 KEYPOINT_MAP {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16} def convert_one(inst): kpts [0] * (17 * 3) for src_idx, dst_idx in KEYPOINT_MAP.items(): x, y, v inst[keypoints][src_idx] kpts[dst_idx*3] x kpts[dst_idx*31] y kpts[dst_idx*32] 2 if v 0 else 0 xs [kpts[i] for i in range(0, len(kpts), 3) if kpts[i2] 0] ys [kpts[i] for i in range(1, len(kpts), 3) if kpts[i2] 0] if not xs: return None x1, y1, x2, y2 min(xs), min(ys), max(xs), max(ys) w, h (x2 - x1) * 1.25, (y2 - y1) * 1.25 cx, cy (x1 x2) / 2, (y1 y2) / 2 bbox [cx - w/2, cy - h/2, w, h] return {keypoints: kpts, bbox: bbox, num_keypoints: sum(1 for i in range(2, len(kpts), 3) if kpts[i] 0)}这段代码里最容易出错的其实是外扩比例和中心点计算我建议转换完一定跑一遍可视化验证。5. 实测踩坑从环境到效果的完整排查链路5.1 环境依赖、CUDA版本与显存溢出环境这块坑主要集中在版本匹配和显存两个地方。CUDA、cuDNN、PyTorch三者版本必须严格对应差一个小版本都可能报no kernel image is available。我现在的固定做法是先确定CUDA版本去PyTorch官网查对应的安装命令用conda新建隔离环境装绝不在base环境里乱来。一次配好导出env.yaml存档换机器直接复现。显存溢出在高分辨率输入下特别常见。HRNet-W48在1024×768输入、batch 32的情况下没有24G显存根本跑不动。解决办法有几个一是用W32替代W48精度掉一点点二是梯度累积假装大batch三是用混合精度训练能省30%到40%显存四是把batch调小加同步BN。我一般首选混合精度效果和节约最平衡。还有个隐蔽的坑PyTorch的显存碎片。明明还有显存却报OOM重启进程就好了。加一句torch.cuda.empty_cache()经常没用根治得靠设置PYTORCH_CUDA_ALLOC_CONFexpandable_segments:True。5.2 多人场景下的漏检与关节错连多人是姿态估计的重灾区。自顶向下的漏检源头在检测器人一多一挤人检框就容易漏或融在一起后面的姿态再好也没用。我的处理是换更强的检测器并及时提NMS阈值。检测框的NMS阈值在拥挤场景调高一点能减少误删但太高又会重复框要按场景标定。自底向上的错连是另一类问题。两个人面对面站着手快碰到一起时PAF很容易把两人的胳膊连串。我加了两道保险一是关节归属的距离约束如果一条候选肢体的两个端点分属两个检测框且两个框的重叠面积很小就降低这条连接的可信度二是长度先验人类肢体的长度比例是有统计规律的明显超长的连接砍掉。加了这两道错连能压下大半。5.3 小目标与遮挡下的精度塌陷小目标是姿态估计的老大难。整张图里一个人只有三四十像素高关节之间就隔着几个像素热力图根本分不开。解决思路两条一是提高输入分辨率把图像放大再喂给网络代价是慢二是用多尺度测试专门在小尺度上补一刀。我在监控场景用的是输入resize到高分辨率加三尺度融合远处行人AP能提不少。遮挡这块除了前面说的数据增强还有一个实用技巧依赖可见关节的几何约束去推断被遮挡关节。人体是刚性骨架已知双肩双髋的位置骨盆中心大致能估出来已知一只手的两个点能约束另一只手的合理范围。这种后处理能把被遮挡点的坐标猜得更合理虽然不算真正可见但视觉上不突兀。5.4 推理速度优化的几条实战路径速度优化我按性价比排序给你第一优先是模型裁剪和量化把模型换小换轻INT8量化在CPU和专用加速芯片上提速明显精度损失控制在1个点内是可以接受的第二是输入分辨率这是影响速度最大的单参数能降就降第三是算子融合和推理引擎把PyTorch模型导出成ONNX再用专门推理引擎跑通常有2到3倍加速第四是批处理把多帧攒一起批推理吞吐量能翻倍。有个反直觉的结论自底向上在单人场景反而比自顶向下慢因为OpenPose的backbone本身分量重。所以别看宣传里自底向上快具体场景具体测别想当然。6. 选型与落地OpenPose和HRNet到底怎么选6.1 一张表看清两条路线的取舍我把两条路线按实际维度拉了个对比选型时照着看就行维度OpenPose自底向上HRNet自顶向下精度COCO AP中等约60出头高70推理耗时与人数关系基本无关线性增长拥挤场景表现分组易错连依赖检测器单人/少人速度偏慢快训练难度中需要PAF监督中高需大量数据部署成熟度高端到端一个模型需串检测器适合场景密集人群、实时监控高精度、少人、离线分析看这张表结论已经很清楚要精度、人数可控、能接受串检测器选HRNet要端到端、人数多、实时选OpenPose或它的变体。我线上部署健身动作分析用的就是HRNet加轻量检测器公共场所人流统计用的是OpenPose的PyTorch复现版。6.2 端侧与移动端部署的现实约束移动端部署是另一个维度的事。模型大小、算子支持、功耗哪个都是硬约束。HRNet-W48动辄两三百兆手机端根本跑不动得先做剪枝和量化。OpenPose的backbone也重但社区有不少轻量版比如用MobileNet替换VGG的版本参数量能压到几兆。端侧还有个杀手锏是专用推理框架的原生模型格式把模型转成目标框架专属格式比如各家手机的推理引擎比通用ONNX Runtime快不少。不过这步的调试成本高量化后精度掉点也常见建议留够验证时间。我的经验是端侧优先保证帧率稳定宁可用小模型降点精度也别让帧率抖动用户体验对抖动比对手慢几毫秒敏感得多。6.3 业务后处理从坐标到可用事件关键点坐标只是原料真正对业务有用的是从坐标推事件。这块往往最费功夫也最有价值。比如动作识别我会先对关键点序列做时序平滑卡尔曼或滑动平均再算关节角度和角速度最后用简单的规则或小分类器判断动作类别。这里有个心得几何特征加规则往往比端到端时序模型更稳、更可解释尤其是样本量不大的时候。还有一个隐蔽的工程点关键点的坐标系要对齐。视频流里可能有裁剪、缩放、镜像如果不同环节坐标系没统一算出来的角度全是错的。我吃过这个亏最后是给每个摄像头维护一套变换矩阵所有后处理都在统一坐标系下算才彻底解决。7. 我在这两条路线里攒下的一些个人体会一路折腾下来我最大的感受是姿态估计的瓶颈很少在模型本身而在数据和工程细节上。你可能花两周调出一个更好的网络结构只为了半个点AP但把标注口径统一、把热力图解码从argmax换成亚像素、把左右翻转索引映射修对轻轻松松就是一两个点而且这些是复现性极强的确定性收益。所以我的精力分配是三成在模型七成在数据管线和后处理。选型上我也想给个提醒别被论文里的SOTA数字绑架。HRNet精度是高但它是自顶向下的你的人检器稍微差一点整体效果可能还不如一个调好的自底向上模型。关键还是看你的真实场景长什么样——人数、遮挡、算力、延迟这四个变量一确定答案基本就浮出来了。最后留个小技巧给要上手的朋友先用COCO预训练权重把整条链路跑通哪怕只跑一张图确认数据加载、坐标反算、可视化这一套全对再去碰训练和优化。我见过太多人一上来就训模型结果卡了三天发现是标注转换的索引错了。链路通了剩下的事都是水到渠成。
返回列表