PifPaf: Composite Fields for Human Pose Estimation
发表于arxiv, 一个bottom-up的方法, 用来预测单张图片中多个人体的关节点位置, 已开源
arxiv地址: https://arxiv.org/abs/1903.06593
github地址: https://github.com/vita-epfl/openpifpaf
2021年新出的3D姿态估计paper:https://arxiv.org/pdf/2103.02440.pdf
github地址:https://github.com/openpifpaf/openpifpaf
文章比较难懂的原因是,这篇文章是多篇文章思想的集合,追根溯源,必须要去看这篇文章引用的文章,你才会看得懂:
《Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields》
《Towards Accurate Multi-person Pose Estimation in the Wild》
《PersonLab: Person Pose Estimation and Instance Segmentation with a Bottom-Up, Part-Based, Geometric Embedding Model》
《Rethinking the Heatmap Regression for Bottom-up Human Pose Estimation》
带着问题看论文
1.不同类(头、身体,不同通道的)怎么连接的?
- 可以参考openpose文章去理解:《Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields》
- 输出特征图的维度是[b, 17, 7,h, w],17个关节的预测在不同channel,但是大小是一样,可以拼到一张图上,因为我们知道,脚和膝盖、膝盖和腰是连接,那先把所有检测出来的脚和所有的膝盖连接起来,之后再做NMS或其他后处理方法去掉不对的连接。
PIF
的offset
图为什么渐进的?而不是指向Ground True的方向?- 文章是在《Towards Accurate Multi-person Pose Estimation in the Wild》文章的基础上,添加pbi,jp_b^{i,j}pbi,j和pσi,jp_\sigma^{i,j}pσi,j,公式也改了,但是含义没变
PAF
怎么产生的,怎么遍历成一个人的?- 借鉴文章《PersonLab: Person Pose Estimation and Instance Segmentation with a Bottom-Up, Part-Based, Geometric Embedding Model》的贪心法
所以,这篇文章就是拼接的
一. 解决问题和贡献
1.1. 解决问题
bottom-up
方案(OpenPose
)在地低分辨率上表现差,文章在《Towards Accurate Multi-person Pose Estimation in the Wild》文章的基础上,添加pbi,jp_b^{i,j}pbi,j和pσi,jp_\sigma^{i,j}pσi,j,将特征图的定位转换到原图上做处理up-bottom
(Mask RCNN
)方案在多人有遮挡的场景上表现差,以及错检
红圈中是错检测,黑框中的是漏检的
Mask RCNN在拥挤的场景漏检
1.2. 贡献
bottom-up
,box-free
,end-to-end cnn architecture
- 提出
Part Intensity Field (PIF)
用来定位人体关节点位置 - 提出
Part Association Field (PAF)
用来确定关节点之间的连接
1.3. 整体结构
二. 关节点定义
过早时期,谷歌提出直接对关键点做回归,通过多次迭代校准关键点的定位(x,y),这样定位还是不是很准确,后来的方法都是基于关键点热力图,将一个关键点Ground True
坐标周围半径R内区域都设为1,之外的区域设为0,转化为分类问题。
三. PIF(Part Intensity Fields)
PIF label
是confidence map
和regression map
的结合
- PIF输出的是[b, 17, 5,h, w]纬度
- b:
batch
- 17:代表预测的关键点个数
h
,w
:特征图的长宽- 5:表示{pci,jp_c^{i,j}pci,j,pxi,jp_x^{i,j}pxi,j,pyi,jp_y^{i,j}pyi,j,pbi,jp_b^{i,j}pbi,j,pσi,jp_\sigma^{i,j}pσi,j}
(i,j)
是输出特征图上的坐标,pci,jp_c^{i,j}pci,j表示输出的(x,y)
表示(i,j)
指向周围关键点真值的方向向量- pci,j:p_c^{i,j}:pci,j:是经过PIF的特征图上
(i,j)
位置的confidence
预测值 - pxi,jp_x^{i,j}pxi,j、pyi,jp_y^{i,j}pyi,j:是经过PIF的特征图上
(i,j)
位置的(x,y)
方向上offset
(偏置)向量 - pbi,jp_b^{i,j}pbi,j:是
Laplace Loss
上的系数,控制关键点热力图的大小 - pσi,jp_\sigma^{i,j}pσi,j:不是高斯的σ\sigmaσ,是用来将特征图还原到原图的比例
- b:
3.1. pci,jp_c^{i,j}pci,j的作用
pci,jp_c^{i,j}pci,j在PIF中代表点(i,j)是否是关键点的置信度,用来判断关键点,在PAF里面用来衡量两点的关联性大小
3.2. pxi,jp_x^{i,j}pxi,j、pyi,jp_y^{i,j}pyi,j的作用
有个这个PIF label
,就可以根据pci,jp_c^{i,j}pci,j,pxi,jp_x^{i,j}pxi,j,pyi,jp_y^{i,j}pyi,j得到位置精度更高的confidence map
,公式如下:
公式展开就是∑i,je−(x−pxi,j)2+(y−pyi,j)22∗(pσi,j)2\displaystyle\sum_{i,j}e^{-\frac{(x-p_x^{i,j})^2+(y-p_y^{i,j})^2}{2*(p_\sigma^{i,j})^2}}i,j∑e−2∗(pσi,j)2(x−pxi,j)2+(y−pyi,j)2
在理解这个公式之前,先看一下《Towards Accurate Multi-person Pose Estimation in the Wild》文章的公式:
hk(xj)h_k(x_j)hk(xj):表示hk(xi)h_k(x_i)hk(xi)热力图(半径R区域)内的其他关键点的热力图
lkl_klk:表示第k个关键点
xix_ixi:表示当前点
xjx_jxj:表示和xix_ixi离lkl_klk等距的所有点
G(xj+Fk(xj)−xi)=G(xj+lk−xj−xi)=G(lk−xi)G(x_j + F_k(x_j)-x_i) = G(x_j + l_k - x_j - x_i) = G(l_k - x_i)G(xj+Fk(xj)−xi)=G(xj+lk−xj−xi)=G(lk−xi) :表示hk(xj)h_k(x_j)hk(xj)的系数,是固定值,也就是离lkl_klk等距的热力图的权重一样
这个公式离说明,特征图上的点xix_ixi离关键点真值lkl_klk越近,lk−xj−xil_k - x_j - x_ilk−xj−xi越小,因为是高斯函数,所以计算得到的权重G就越大,说明对计算的fk(xi)f_k(x_i)fk(xi)的贡献越大,这也符合逻辑
同样的,本篇论文的公式也是表示越近的点权重越大,只不过距离是offset
与(x,y)的距离。所以这就是为什么相近的offset(图像种的箭头)方向很接近,远的相差远,呈现渐变的感觉:
- 图(a)是
PIFlabel
里的pci,jp_c^{i,j}pci,j - 图(b)是PIF预测的结果
offset
:pxi,jp_x^{i,j}pxi,j,pyi,jp_y^{i,j}pyi,j ,放大后可以看出方向是渐变的,相近的向量方向相近,不仔细分析注意不到这点 - 图©是三者融合之后的结果. 可以看出来点的位置更精确, 中心处的响应值更强, 边缘处更弱
3.3. pbi,jp_b^{i,j}pbi,j的作用
用来控制同一张图片上不同大小的目标物的关键点热力图(Heatmap
)大小(大的物体,关键点热力图区域就应该大),文章中半径为3σ3\sigma3σ,loss函数如下:
- |x−μ∣/b|x - \mu|/b|x−μ∣/b作为指数函数的幂次,就是e−(x−μ)2∗(bσ)2e^{-\frac{(x-\mu)}{2*(b\sigma)^2}}e−2∗(bσ)2(x−μ),所以pbi,jp_b^{i,j}pbi,j相当于是对σ\sigmaσ值加权
拓展: 《Rethinking the Heatmap Regression for Bottom-up Human Pose Estimation》论文中也考虑了不同Scale目标应该有不同大小热力图的问题
区别是,文章Scale-Adaptive Heatmap Regression
采用增加一个分支去计算Scale maps
,得到不同Scale的目标应该有的热力图大小,对预测的Heatmaps
重加权;因为Scale maps
会导致到特征图出现形变,所以在Loss里面加了正则项:
Scale-Adaptive Heatmap Regression
会导致背景数量减少,前景和背景样本不均衡,所以加了Weight-Adaptive Heatmap
Regression:
就是借鉴Focal Loss
处理类别不均衡和难易样本不均衡问题
想了解详细,可以去知乎看作者的讲解:CVPR 2021 论文解读Vol.7 | “自底向上”人体姿态估计的尺度自适应方法
3.4. pσi,jp_\sigma^{i,j}pσi,j的作用
pσi,jp_\sigma^{i,j}pσi,j:不是高斯的σ\sigmaσ,是用来将特征图还原到原图进行处理的比例系数,论文里没有详细说明,但是代码(openpifpaf-main/src/openpifpaf/csrc/src/cif_hr.cpp
)中可以看出:
void CifHr::accumulate(const torch::Tensor& cif_field, int64_t stride, double min_scale, double factor) {if (ablation_skip) return;auto cif_field_a = cif_field.accessor<float, 4>();float min_scale_f = min_scale / stride;float v, x, y, scale, sigma;for (int64_t f=0; f < cif_field_a.size(0); f++) {for (int64_t j=0; j < cif_field_a.size(2); j++) {for (int64_t i=0; i < cif_field_a.size(3); i++) {v = cif_field_a[f][1][j][i];if (v < threshold) continue;scale = cif_field_a[f][4][j][i]; // 每个点(j,i)的scale不一样,相当于权重if (scale < min_scale_f) continue;x = cif_field_a[f][2][j][i] * stride;y = cif_field_a[f][3][j][i] * stride;sigma = fmaxf(1.0, 0.5 * scale * stride); // 通过stride还原到原图尺寸,scale可以学习的参数// Occupancy covers 2sigma.// Restrict this accumulation to 1sigma so that seeds for the same joint// are properly suppressed.add_gauss(f, v / neighbors * factor, x, y, sigma, 1.0);}}}
}void CifHr::add_gauss(int64_t f, float v, float x, float y, float sigma, float truncate) {auto accumulated_a = accumulated.accessor<float, 3>();auto minx = std::clamp(int64_t(x - truncate * sigma), int64_t(0), accumulated_a.size(2) - 1); //x < truncate * sigma,等于0auto miny = std::clamp(int64_t(y - truncate * sigma), int64_t(0), accumulated_a.size(1) - 1);// -siga < x < sigma -> minx=0 -> x + sigma + 1 > 0 + 1 -> maxx = x + sigma + 1 (0, x + sigma + 1)// x < -sigma -> minx=0 -> x + sigma + 1 < 0 + 1 -> maxx = min + 1 = 1 (0, 1)// x > sigma -> minx= x - sigma -> x + sigma + 1 > x - sigma + 1 -> maxx = x + sigma + 1 (x - sigma, x + sigma + 1 || accumulated_a.size(1) - 1)auto maxx = std::clamp(int64_t(x + truncate * sigma + 1), minx + 1, accumulated_a.size(2)); auto maxy = std::clamp(int64_t(y + truncate * sigma + 1), miny + 1, accumulated_a.size(1));float sigma2 = sigma * sigma;float truncate2_sigma2 = truncate * truncate * sigma2;float deltax2, deltay2;float vv;for (int64_t xx=minx; xx < maxx; xx++) {// x < -sigma -> xx = x = 0 -> deltax2 = 0deltax2 = (xx - x) * (xx - x); for (int64_t yy=miny; yy < maxy; yy++) {deltay2 = (yy - y) * (yy - y);if (deltax2 + deltay2 > truncate2_sigma2) continue;if (deltax2 < 0.25 && deltay2 < 0.25) {// this is the closest pixelvv = v;} else {vv = v * approx_exp(-0.5 * (deltax2 + deltay2) / sigma2);}auto& entry = accumulated_a[f][yy][xx];entry = fmaxf(entry, revision) + vv;entry = fminf(entry, revision + 1.0);}}
}
cif_field_a[f][1][j][i]
:pci,jp_c^{i,j}pci,jcif_field_a[f][2][j][i]
、cif_field_a[f][3][j][i]
:pxi,jp_x^{i,j}pxi,j,pyi,jp_y^{i,j}pyi,jcif_field_a[f][4][j][i]
:pσi,jp_\sigma^{i,j}pσi,j
四. PAF (Part Association Fields)
- PAF label的输出是[b, 17, 7,h, w]纬度
- 7:表示{aci,ja_c^{i,j}aci,j,ax1i,ja_{x1}^{i,j}ax1i,j,ay1i,ja_{y1}^{i,j}ay1i,j,pb1i,jp_{b1}^{i,j}pb1i,j,ax2i,ja_{x2}^{i,j}ax2i,j,ay2i,ja_{y2}^{i,j}ay2i,j,pb2i,jp_{b2}^{i,j}pb2i,j}
- $a_c^{i,j}:代表(i,j)的
confidence
- {ay1i,ja_{y1}^{i,j}ay1i,j,pb1i,jp_{b1}^{i,j}pb1i,j}和{ax2i,ja_{x2}^{i,j}ax2i,j,ay2i,ja_{y2}^{i,j}ay2i,j}:分别代表(i,j)该点到真正的两个
ground truth
关键点的(x_offset, y_offset)
- pb1i,jp_{b1}^{i,j}pb1i,j、pb2i,jp_{b2}^{i,j}pb2i,j:是相对应的两个用来计算
loss
的系数
- $a_c^{i,j}:代表(i,j)的
- 7:表示{aci,ja_c^{i,j}aci,j,ax1i,ja_{x1}^{i,j}ax1i,j,ay1i,ja_{y1}^{i,j}ay1i,j,pb1i,jp_{b1}^{i,j}pb1i,j,ax2i,ja_{x2}^{i,j}ax2i,j,ay2i,ja_{y2}^{i,j}ay2i,j,pb2i,jp_{b2}^{i,j}pb2i,j}
理解PAF流程之前,先看看OpenPose的流程:
17个关节点分别用17个channel的特征图去预测
(a)根据先验知识:右腰和右肩有连接,左腰和左肩有连接,将左腰channel上通过PIF检测出来的所有关键点,和左肩channel上通过PIF检测出来的所有关键点连接,不需要考虑对不对
(b)通过连接线的中点是否落在向量空间来决定连接线是否正确:
公式中的limb c
:代表手臂(手和手肘的连接线),
公式中k
:代表地个人
公式中σ\sigmaσ:学习得到
图中j1
、j2
代表ground point
,第j1、j2个关键点
图中P点:就是我们要判断的预测连接线中点
图中v
:代表j1到j2的单位向量
即P点落在limb c与垂直方向的单位向量v组成的向量区域内,那就是预测正确,否则连接线错误,即这两个预测的关键点之间没有关联,不属于同一个人
还是不懂的可以去B站看这个视频:B站:第3课 人体骨骼点检测:自底向上
(c)通过(b)后只剩下有连线中点有交叉的部分,都在向量区域,满足条件的错误连线。通过大小是超参数的区域做NMS(非极大抑制)或者匈牙利算法,抑制掉有交叉的(计算得到的)低关联度连接线,得到(c)图
不同的是,不是直接连线预测的关键点作为连接线,而是通过:对特征图中所有(i,j)
点,首先找到离它最近的预测的关键点,如图(b)的短箭头:
然后通过先验知识知道第一个关键点和其他channel的关键点有连接关系,获取第二个关键点,通过如下关系计算得到通过(i,j)
连接的两个预测的关键点之间的关联度PAF:
- x:(i,j)到关键点1的连线
- aca_cac:PAF输出的
confidence
aci,ja_c^{i,j}aci,j - a1:PAF输出的ax1i,ja_{x1}^{i,j}ax1i,j,ay1i,ja_{y1}^{i,j}ay1i,j
- b1b_1b1:代表pb1i,jp_{b1}^{i,j}pb1i,j
- f2(ax2,ay2)f_2(a_{x2},a_{y2})f2(ax2,ay2):利用PIF的公式更新得到的关键点2的新
confidence
五. 解码后处理(Greedy Decoding)
得到PIF和PAF后,为了确保根据PAF找到的两个点确实是应该连到一起的, 程序会执行reverse操作, 即如果通过point a找到了point b, 那么就会从point b找到point c, 如果point a和point c之间的距离小于设定好的阈值, 那么就说明这两个点应该被连在一起. 计算出来哪些点需要连在一起之后, 然后通过NMS方式将多连接的线去除掉,直到完整的pose被找到。
六.其他
文章对Smooth L1
和Laplace Loss
做了对比实验,Laplace Loss
加上尺度因子b
效果更好
参考文章:
【1】CSDN:PifPaf: Composite Fields for Human Pose Estimation
PifPaf: Composite Fields for Human Pose Estimation相关推荐
- 姿态估计之2D人体姿态估计 - PifPaf:Composite Fields for Human Pose Estimation
参考: PifPaf: Composite Fields for Human Pose Estimation_MatthewHsw的博客-CSDN博客 OpenPifPaf: encoder过程_Ma ...
- 重新思考人体姿态估计 Rethinking Human Pose Estimation
Newly updated by 2019-11-19 ----------------------------------------------------- 浅谈:2D人体姿态估计基本任务.研究 ...
- 人体姿态估计(Human Pose Estimation)技巧方法汇总
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 作者:Poeroz https://zhuanlan.zhihu.com/p/10 ...
- Human Pose Estimation人体姿态估计综述调研
给定一幅图像或一段视频,人体姿态估计就是去恢复其中人体关节点位置的过程. 数据集 LSP 地址:http://sam.johnson.io/research/lsp.htm 样本数:2K 关节点个数: ...
- Human Pose Estimation姿态估计调研
介绍 姿态估计的目标是在RGB图像或视频中描绘出人体的形状,这是一种多方面任务,其中包含了目标检测.姿态估计.分割等等.有些需要在非水平表面进行定位的应用可能也会用到姿态估计,例如图形.增强现实或者人 ...
- Survey on Human pose estimation
关于姿态估计的一些总结,GitHub上搬的 Papers 2D Pose estimation Learning Human Pose Estimation Features with Convolu ...
- 论文阅读笔记--Monocular Human Pose Estimation: A Survey of Deep Learning-based Methods 人体姿态估计综述
趁着寒假有时间,把之前的论文补完,另外做了一点点笔记,也算是对论文的翻译,尝试探索一条适合自己的论文阅读方法. 这篇笔记基本按照原文的格式来,但是有些地方翻译成中文读起来不太顺,因此添加了一些自己的理 ...
- Simple Baselines for Human Pose Estimation 阅读笔记
SimpleBaseline姿态估计阅读笔记 ECCV2018 论文链接 代码链接 摘要: 近年来,姿态估计在取得重大进展的同时,总体算法和系统复杂性也日益增加,加剧了算法分析和比较的难度,本项工作提 ...
- 2D/3D人体姿态估计 (2D/3D Human Pose Estimation)
1. 基本概念 算法改进入口 网络设计 特征流 损失函数 数据集的重要性:只要有一个好的.针对性的数据集,问题都可以解决 过集成新一代AutoML技术,可降低算法试错成本 人体姿态估计(Human P ...
最新文章
- 二维非稳态导热微分方程_第三章非稳态导热分析解法
- 空间金字塔方法表示图像
- java的知识点23——泛型Generics、Collection接口、List特点和常用方法、 ArrayList特点和底层实现
- Java面向对象(二)
- MySQL 中日志的面试题总结
- 如何使用django显示一张图片
- eval函数pythonmopn_python3中的 eval函数
- Vs2010架构设计-层图(Layer Diagram)
- Container(容器)与 Injector(注入)
- CCF201712-1 最小差值
- STM32使用DMA接收串口数据
- Android8.0 HIDL绑定式和直通式区别
- 测试驱动的项目管理概念文档
- 3.python(第三天日记)
- WindowXP下PHP5开发环境配置 (转载)
- Spring Boot干货系列:(十二)Spring Boot使用单元测试
- echarts 画四川省地图 点击高亮并获取各市区参数
- 阿里中台搞了3年,凉了?网传:副总裁玄难“背锅”,辞职创业!咸鱼放弃维护 Flutter!...
- 阿里云服务器怎么预防CC攻击?
- WEditor USB device is offline
热门文章
- 迁移学习和finetune的区别及迁移学习代码实现
- Ubuntu 14.04(64位)安装和使用docker
- 网页版邮箱提取/采集软件
- CSS“隐藏”元素的几种方法的对比
- linux主机挂软件,推荐Linux服务器面板宝塔软件
- android视频动态壁纸app,手机壁纸视频动态壁纸
- 在写CSDN的文章时,如何插入表格并进行简单的配置
- 【开源毕设】一款精美的家校互动APP分享——爱吖校推 [你关注的,我们才推](持续开源更新2)
- ADAM : A METHOD FOR STOCHASTIC OPTIMIZATION
- 关于pd.read_csv() 读数据的注意事项