前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenPose 基于OpenCV DNN 的多人姿态估计

OpenPose 基于OpenCV DNN 的多人姿态估计

作者头像
AIHGF
修改2020-06-11 16:35:31
4.9K4
修改2020-06-11 16:35:31
举报
文章被收录于专栏:AIUAIAIUAI

原文: OpenPose 基于OpenCV DNN 的多人姿态估计 - AIUAI

OpenPose 可以对图片中单个人体目标的姿态估计,也可以处理图片中多人的姿态估计.

OpenPose 基于OpenCV DNN 的单人姿态估计 - AIUAI

这里主要记录基于 OpenCV 4.x DNN 模块和 OpenPose 开源模型的多人人体姿态估计 的实现.

采用的模型的基于 COCO 数据集训练的人体关键点模型.

1. OpenPose 网络结构

OpenPose 的多人人体姿态估计的模型结构如图:

image
image

网络输入为 hxwx3 的图片,并输出包含关键点(Keypoints)的置信图(confidence maps) 和每个关键点对(keypoint pair) 的 Part Affinity Heatmaps 的两个输出数组.

[1] - Stage 0:

采用 VGGNet 的前 10 层,提取输入图片的特征图(feature maps).

[2] - Stage 1:

采用 2-分支的 multi-stage CNN 网络结构:

(1) - 分支一

网络分支一预测人体关键点位置的 2D Confidence Maps ,如 elbow, knee, etc. 每个 Confidence Map 是一个灰度图(grayscale image),其最大值的位置坐标即为对应人体某个关键点的概率最高. 如图:

image
image

(2) - 分支二:

网络分支二预测 Part Affinities (PAF) 的2D 向量场(L, vector fields),其表示了两个关键点之间关联度(degree of association). 例如,关键点 Neck 和 Left Shoulder 之间的 Part Affinity, 如下图,属于同一个人体的关键点之间的 Affinity 值比较大.

image
image

总体来说,Confidence Maps 用于检测关键点位置;而 Affinity Maps 用于检测关键点之间的有效连接.

2. OpenPose 的 OpenCV DNN 实现

根据检测过程,主要涉及的函数有:getKeyponts()getValidPairs()getPersonwiseKeypoints() .

2.1. 模型加载

2.2. 关键点检测

2.2.1. getKeyponts( )函数

**getKeyponts( )函数功能:**对 Confidence Map 采用 NMS(Non Maximum Suppression) 来检测关键点.

2.2.2. 关键点 mapMask
image
image
2.2.3. 关键点坐标值
image
image

2.3. 有效关键点对检测

2.3.1. getValidPairs()函数

**getValidPairs()函数功能:**检测所有人体之间不同关键点之间的有效连接.

2.3.2. 关键点对检测具体实现分析

有效的关键点对(joint pair) 是指两个关键点的连接,属于相同的人体.

最简单的方式是,计算一个关键点与其它所有可能的关键点之间的最小距离,来判断关键点对的有效性.

例如下图,可以计算 Nose 关键点与其它所有 Necks 关键点之间的距离,最小距离的 Neck 关键点,则对应于同一个人体.

image
image

但是,这种方法不是对所有的关键点对都是有效的,尤其是对与图像中包含很多人体,或者有关键点缺失的时候.

例如下图,对于关键点对, Left-Elbow -> Left Wrist,第三个人体的 wrist 关键点与第二个人体的 elbow 关键点的距离,比与其同一人体的 elbow 关键点的距离更小. 但该关键点对并不是有效的.

image
image

而 Part Affinity Maps 的作用是,给定沿着两个关键点对的仿射(affinity)的方向. 因此,有效的关键点对不仅具有最小的距离,其方向也应该顺着 PAF Heatmaps 方向.

例如,Left-Elbow -> Left Wrist 连接的 Heatmap,如下图,即使最小距离的关键点是错误的,但,由于 PAF 只能顺着 Elbow 和 Wrist 的单位向量,所以能正确检测有效的关键点对:

image
image

OpenPose 中采用的方法为:

[1] - 将关键点对的两个点之间的连线进行划分,得到该连线上的 n 个点(Divide the line joining the two points comprising the pair. Find n points on this line.);

[2] - 判断这些点上的 PAF 是否与连接该关键点的线的方向相同(Check if the PAF on these points have the same direction as that of the line joining the points for this pair);

[3] - 如果方向满足特定程度,则为有效的关键点对(If the direction matches to a certain extent, then it is valid pair.)

代码实现与分析:

对于每个关键点对(body part pair, keypoints pair),

[1] - 选择属于同一个关键点对的关键点. 并分别存放在两个列表: candAcandB. candA 列表中的每个关键点可以与 candB 中的某些关键点相连接. 如下图,给出了 candAcandB 中的 Neck -> Right-Shoulder 关键点对的所有关键点:

image
image

对应 Python 实现:

[2] - 计算两个关键点之间的单位向量,其给定了关节点之间连线的方向.

[3] - 计算两个关键点之间连线的 10 个插值点.

[4] - 计算插值点的 PAF 与单位向量 d_ij 之间的点积(dot product).

[5] - 如果这些插值点的 70% 的都满足判定标准,则该关键点对是有效的.

2.4. 同一人体关键点的组合

2.4.1. getPersonwiseKeypoints() 函数

**getPersonwiseKeypoints()函数功能:**计算得到属于每个人体的关键点集合.

对于每个检测到的有效 joint pair,分配属于一个人体的 joints.

2.4.2. 关键点组合的具体实现分析

计算得到所有关键点之间的关键点对后,可以将具有相同关键点检测候选值的关键点对,组合为多人的姿态估计.

代码实现具体分析

[1] - 首先创建保存每个人体的所有关键点的空列表.

然后对每个关键点对,判断 partA 是否已经在列表里, 如果已经在列表里,则表示该关键点对属于该列表,且 partB 也属于同一人体. 因此,添加该关键点对的 partB 到 partA 所在的列表.

[2] - 如果 partA 不在任一人体列表里,则表示该关键点对属于一个新出现的人体,故创建新的列表.

2.5. 姿态检测结果可视化

如:

image
image

3. 完整实现

模型下载:

COCO: http://posefs1.perception.cs.cmu.edu/OpenPose/models/pose/coco/pose_iter_440000.caffemodel

如:

image
image

4. 参考资料

[1] - Multi-Person Pose Estimation in OpenCV using OpenPose - 2018.09.11

[2] - Github - spmallick/learnopencv/OpenPose-Multi-Person

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年03月29日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. OpenPose 网络结构
  • 2. OpenPose 的 OpenCV DNN 实现
    • 2.1. 模型加载
      • 2.2. 关键点检测
        • 2.2.1. getKeyponts( )函数
        • 2.2.2. 关键点 mapMask
        • 2.2.3. 关键点坐标值
      • 2.3. 有效关键点对检测
        • 2.3.1. getValidPairs()函数
        • 2.3.2. 关键点对检测具体实现分析
      • 2.4. 同一人体关键点的组合
        • 2.4.1. getPersonwiseKeypoints() 函数
        • 2.4.2. 关键点组合的具体实现分析
      • 2.5. 姿态检测结果可视化
      • 3. 完整实现
      • 4. 参考资料
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档