MMPose | 关于自顶向下 2D HPE 算法的,全都在这里啦!

简介: 2D Human Pose Estimation (以下简称 2D HPE )旨在从图像或者视频中预测人体关节点(或称关键点,比如头,左手,右脚等)的二维空间位置坐标。2D HPE 的应用场景非常广泛,包括动作识别,动画生成,增强现实等。

2D Human Pose Estimation (以下简称 2D HPE )旨在从图像或者视频中预测人体关节点(或称关键点,比如头,左手,右脚等)的二维空间位置坐标。2D HPE 的应用场景非常广泛,包括动作识别,动画生成,增强现实等。


传统的 2D HPE 算法,设计手工特征提取图像信息,从而进行关键点的检测。近年来随着深度学习的快速发展,基于深度学习的 2D HPE 算法取得了重大突破,算法精度得到了大幅提升。


当前主流的 2D HPE 方法主要可以分为自底向上(bottom up)和自顶向下(top down)两种方式。自底向上的方法同时预测图片中的所有关键点,然后将不同类型的关键点组合成人体。自顶向下的方法首先检测出输入图片中的一个或者多个人,然后对于每个个体单独预测其关键点。自底向上方法的推断时间不随人数的增加而上升,而自顶向下的方法对于不同尺寸的人体更加鲁棒。


本文将结合 MMPose 对自顶向下的 2D HPE 算法做一些介绍。


本文内容


主流算法

   基于回归坐标的方法

   基于热图(heatmap)的方法

常用数据集

   COCO

   MPII

   CrowdPose

MMPose 中的 2D HPE 算法实现

   模型

   数据

训练配置

Optimizer

   Learning rate policy


1.  主流算法



基于回归坐标的方法


早期一些自顶向下的深度学习方法用神经网络直接预测人体关键点的 2D 坐标 。

640.png

DeepPose 是这类方法的经典代表。DeepPose 采用级联的神经网络来预测人体各个关键点的相对坐标。每一个阶段都拿上一阶段的输出坐标作为输入,并进一步预测更为准确的坐标位置。最终,将预测得到的归一化的相对坐标转换为绝对坐标。


直接回归坐标的方法思路直接,可以直接获得关键点位置,往往有更快的预测速度。然而,由于人体姿态的自由度很大,直接预测坐标的建模方式对神经网络的预测并不友好,预测精度受到了一定制约。


基于热图(heatmap)的方法


近些年,基于热图(heatmap)的人体姿态估计方法成为了主流。基于热图的方法在每个位置预测一个分数,来表征该位置属于关键点的置信度。根据预测的热图,进一步提取关键点的坐标位置。


基于热图的方法更好地保留了空间位置信息,更符合卷积神经网络(Convolutional Neural Network, CNN)的设计特性,从而取得了更好的预测精度

640.png

CPM(Convolutional Pose Machines) 利用序列化的卷积神经网络来学习纹理信息和空间信息,实现2D人体姿态估计。CPM通过设计多阶段的网络结构逐渐扩大网络的感受野,获取远距离的结构关系。每一阶段融合空间信息,纹理信息和中心约束来得到更为准确的热图预测。


CPM :

https://mmpose.readthedocs.io/en/latest/papers/backbones.html#cpm-cvpr-2016


640.pngStacked Hourglass 通过多尺度特征融合,整合人体结构化的空间关系。该方法连续进行上采样和下采样,并在网络中间利用热图进行监督,提升了网络的性能。


Stacked Hourglass :

https://mmpose.readthedocs.io/en/latest/papers/backbones.html#hourglass-eccv-2016

640.png



SBL(Simple Baseline) 为人体姿态估计提供了一套基准框架。SBL在主干网络后接反卷积模块来预测热图,通过非常简单的设计获得了出色的性能。


SBL :

https://mmpose.readthedocs.io/en/latest/papers/algorithms.html#simplebaseline2d-eccv-2018

640.png



HRNet  针对人体姿态估计设计了一个高效的网络结构。不同于以往方法利用低分辨率的特征预测高分辨率的热图,HRNet 设计了多个不同分辨率的平行分支。


高分辨率特征始终被保持,并且不同尺度的特征能够相互融合。这种设计结合局部纹理特征和全局语义信息,实现了更加准确和鲁棒的姿态预测。


HRNet :

https://mmpose.readthedocs.io/en/latest/papers/backbones.html#hrnet-cvpr-2019

640.png

最近,一些研究专注于解决自顶向下的 2D HPE 中存在的问题。


DARK 研究热图和坐标之间的转换关系。其改进关键点坐标的编码过程,生成无偏差的精确热图分布用以模型训练。同时,该方法提出了基于泰勒展开的热图解码过程,降低了基于热图方法带来的量化误差。此外,LiteHRNet 和 VIPNAS 从 2D HPE 在实际应用中模型低复杂度的需求出发,提出了轻量级的高效网络。


2. 常用数据集



MMPose 目前支持 COCO,MPII ,CrowdPose 等 9 种常用的 2D 人体关键点数据集。我们也提供了数据预处理脚本和数据集链接,帮助用户快速得到训练所需的数据。


COCO


COCO数据集是目前最常用的多人人体关键点检测数据集。COCO数据集包含多达 330K 张图片,200K 个标注的人体,是主流的大规模人体关键点数据集。COCO 数据集将人体表示为 17 个关键点,包括鼻子,左右眼,左右耳,左右肩,左右肘,左右腕,左右臀,左右膝,左右脚踝。

640.png

图片摘自 MS COCO 官网


COCO 数据集关键点检测的评价指标模拟目标检测的评估指标,采用平均精确度(average precision, AP)和平均召回率(average recall, AR)进行评测。其通过定义对象关键点相似度(object keypoint similarity, OKS)来度量预测姿态和真实姿态的匹配相似性,并计算 AP 在 OKS 取值范围(0.50:0.05:0.95)的平均值 mAP 作为主要的衡量指标。


最近,Jin 等人提出了 COCO-WholeBody 数据集,对COCO 数据集进行扩展,将关键点标注从身体的17个关键点扩展为了全身 133 个关键点。由于该数据集对人脸、人手、人脚等重要部位进行了精细标注,可以用于评估全身人体姿态估计的效果,也可以用于 2D 人脸关键点估计、2D人手关键点估计等任务之中。


COCO数据集:

https://mmpose.readthedocs.io/en/latest/tasks/2d_body_keypoint.html#coco


COCO-WholeBody 数据集:

https://mmpose.readthedocs.io/en/latest/tasks/2d_wholebody_keypoint.html#coco-wholebody


MPII


MPII数据集是重要的单人/多人人体关键点检测数据集。MPII 数据集包含图片数 25K,标注的人体数 40K,每个人体用 16 个关键点表示。数据集图片来源于 YouTube 视频,包含了410种常见活动。准确关键点百分比(Percentage of Correct Keypoints, PCK)被广泛用于评估关键点的准确性,代表了预测关键点与其对应的真实关键点间的归一化距离小于设定阈值的比例。MPII 数据集的评价指标,是以头部长度( head length ) 作为归一化参考的准确关键点百分比,即 PCKh 。

640.png

图片摘自CPM论文


MPII 数据集:

https://mmpose.readthedocs.io/en/latest/tasks/2d_body_keypoint.html#mpii


CrowdPose


CrowdPose数据集是近年来提出的密集场景下存在大规模遮挡的2D人体关键点数据集。Li 等人提出了密集指数(CrowdIndx),用来表征图片中人群的密集程度。依此构建的CrowdPose数据集,包含20K的图片数,且具有均匀的密集指数的分布,适合评估算法在密集场景的效果。CrowdPose数据集采用了和COCO数据集一致的评价指标,即mAP。

640.png

图片摘自CrowdPose论文


CrowdPose数据集:

https://mmpose.readthedocs.io/en/latest/tasks/2d_body_keypoint.html#crowdpose


3. MMPose 中的 2D HPE 算法实现



MMPose现已支持 DeepPose , CPM , Hourglass 和HRNet 等十余种不同的算法模型。


我们也提供了基于图像和视频的 demo,感兴趣的话不妨先尝试一下~

640.png

demo 链接 :

https://mmpose.readthedocs.io/en/latest/demo.html#d-human-pose-demo



3. 1 模型


Backbone


模型的骨干网络(Backbone)为 CPM 模型(具体实现见 cpm.py ),输入为 3 通道的图片,输出为K通道的热度图,其中K为关键点的个数。CPM 的网络结构中,包括num_stages=6 个阶段的CPM网络模块,逐渐优化关键点的预测结果。

backbone=dict(
    type='CPM', # 骨干网络的类型
    in_channels=3, # 输入通道数
    out_channels=channel_cfg['num_output_channels'], # 输出通道数
    feat_channels=128, # 特征维度
    num_stages=6) # 模型阶段数


Head


模型的Head部分,我们采用了TopdownHeatmapMultiStageHead,具体实现见topdown_heatmap_multi_stage_head.py 。


topdown_heatmap_multi_stage_head.py 链接 :

https://github.com/open-mmlab/mmpose/blob/master/mmpose/models/heads/topdown_heatmap_multi_stage_head.py


该网络头用于处理多阶段的骨干网络提取的特征,并输出多阶段的预测结果。模型训练的损失函数为JointsMSELoss ,即热度图上的二范数损失函数。

keypoint_head=dict(
    type='TopdownHeatmapMultiStageHead', # 网络头的类型
    in_channels=channel_cfg['num_output_channels'], # 输入通道数
    out_channels=channel_cfg['num_output_channels'], # 输出通道数
    num_stages=6, # 模型阶段数
    num_deconv_layers=0, # 反卷积层数量
    extra=dict(final_conv_kernel=0, ), # final_conv 为 identity函数
    loss_keypoint=dict(
        type='JointsMSELoss', # 损失函数类别
        use_target_weight=True)) # 在损失计算中,是否考虑target_weight的影响

3. 2 数据


Data config


以下是与训练数据相关的一些配置,具体实现见 topdown_coco_dataset.py 。


topdown_coco_dataset.py 链接 :

https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py

data_cfg = dict(
    image_size=[192, 256], # 输入图片尺寸w, h
    heatmap_size=[24, 32], # 输出热度图的尺寸 W, H
    num_output_channels=channel_cfg['num_output_channels'], # 输出的通道数
    num_joints=channel_cfg['dataset_joints'], # 关键点个数
    dataset_channel=channel_cfg['dataset_channel'], # 数据集所对应的通道列表
    inference_channel=channel_cfg['inference_channel'], # 模型输出的通道列表
    soft_nms=False, # 测试阶段,是否使用soft-nms
    nms_thr=1.0, # nms的阈值
    oks_thr=0.9, # oks (目标关键点相似度)阈值,用于nms操作
    vis_thr=0.2, # 关键点可见性阈值
    use_gt_bbox=False, # 测试阶段,是否使用人工标注的人体框
    det_bbox_thr=0.0, # 检测框的阈值,只用于 use_gt_bbox=False
    bbox_file='data/coco/person_detection_results/'
    'COCO_val2017_detections_AP_H_56_person.json', # 检测框的文件路径
)
data_root = 'data/coco' # 数据集路径
data = dict(
    samples_per_gpu=64, # 训练阶段,每张GPU的批处理大小
    workers_per_gpu=2, # 每个GPU的数据读取线程数量
    val_dataloader=dict(samples_per_gpu=32), # 验证阶段,每张GPU的批处理大小
    test_dataloader=dict(samples_per_gpu=32), # 测试阶段,每张GPU的批处理大小
    train=dict(
        type='TopDownCocoDataset', # 训练数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_train2017.json', # 标签路径
        img_prefix=f'{data_root}/train2017/', # 图片路径前缀
        data_cfg=data_cfg,
        pipeline=train_pipeline),
    val=dict(
        type='TopDownCocoDataset', # 验证数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_val2017.json',
        img_prefix=f'{data_root}/val2017/',
        data_cfg=data_cfg,
        pipeline=val_pipeline),
    test=dict(
        type='TopDownCocoDataset', # 测试数据集名称
        ann_file=f'{data_root}/annotations/person_keypoints_val2017.json',
        img_prefix=f'{data_root}/val2017/',
        data_cfg=data_cfg,
        pipeline=val_pipeline),
)


Pipeline


数据预处理的 pipeline 主要由以下几个步骤组成:


1. LoadImageFromFile:读取图片。

2. TopDownRandomFlip:随机水平翻转。

3. TopDownHalfBodyTransform:半身肢体数据增强,生成一些只有上半身或下半身的人体框。

4. TopDownGetRandomScaleRotation:随机旋转和缩放。

5. TopDownAffine:进行仿射变换。

6. ToTensor:图片转换为Tensor。

7. NormalizeTensor:输入Tensor归一化,减均值,除方差。

8. TopDownGenerateTarget:根据标签,生成 GT 热度图。

9. Collect:整合训练中需要用到的数据。

train_pipeline = [
    dict(type='LoadImageFromFile'), # 读取图片
    dict(type='TopDownRandomFlip', # 数据增强:随机翻转
        flip_prob=0.5), # 翻转概率
    dict(
        type='TopDownHalfBodyTransform', # 数据增强:生成半身肢体
        num_joints_half_body=8, # 半身肢体生成的阈值,至少包含8个关键点
        prob_half_body=0.3), # 半身肢体生成的概率
    dict(
        type='TopDownGetRandomScaleRotation', # 数据增强:随机缩放和旋转
        rot_factor=40, # 随机旋转幅度 [-2*rot_factor, 2*rot_factor]
        scale_factor=0.5), # 随机缩放幅度 [1-scale_factor, 1+scale_factor]
    dict(type='TopDownAffine'), # 仿射变换
    dict(type='ToTensor'), # 数据格式转换为 Tensor
    dict(
        type='NormalizeTensor', # 输入Tensor归一化
        mean=[0.485, 0.456, 0.406], # 归一化均值
        std=[0.229, 0.224, 0.225]), # 归一化方差
    dict(type='TopDownGenerateTarget', # 根据标签,生成GT热图
        sigma=2), # 热度图高斯分布的标准差
    dict(
        type='Collect', # 整合训练中所需要的数据
        keys=['img', 'target', 'target_weight'], # 保留的key
        meta_keys=[ # 保留的meta-key
            'image_file', 'joints_3d', 'joints_3d_visible', 'center', 'scale',
            'rotation', 'bbox_score', 'flip_pairs'
        ]),
]

3.3 训练配置



Optimizer


采用Adam作为优化器,并设置初始学习率为 5e-4。

optimizer = dict(
    type='Adam', # 优化器的类型
    lr=5e-4, # 基础学习率
)
optimizer_config = dict(grad_clip=None) # 不进行梯度裁剪

Learning rate policy


学习率采用阶梯状衰减,分别在第170和第200个epoch,降低学习率(默认每次降低到 0.1倍),总计训练210个epoch。


我们采用了预热启动(warmup)策略,初始设置非常小的学习率 ( 0.001 倍的初始学习率 lr ),并在前 500 个迭代轮次中,线性增加为 lr=5e-4 。

lr_config = dict(
    policy='step', # 学习率调整策略
    warmup='linear', # 预热启动策略
    warmup_iters=500, # 预热启动的训练迭代数
    warmup_ratio=0.001, # 预热启动阶段初始学习率为 warmup_ratio * lr
    step=[170, 200]) # 学习率下降的轮次,分别在第170和第200个epoch,降低学习率
total_epochs = 210 # 总迭代轮数

本文介绍了 2D HPE 一些自顶向下的算法和常用的数据集,并以CPM为例,介绍了MMPose中的具体算法实现。


希望大家通过本文的阅读能够对2D HPE有一个初步的认识,也欢迎大家使用MMPose来支持相关的研究与应用~


文章来源:公众号【OpenMMLab】

2021-09-06 19:01

相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
目录
相关文章
|
存储 算法 前端开发
从一道hard的leetcode到2d包围盒算法
前言 大家好,哈哈哈最近国庆在家无聊比较boring,然后最近也在学习算法,之前我是从来没有做过hard的题目。想着胖虎来挑战下。然后这道题也比较有意思,我不是什么算法大佬,我只是觉得这篇很有意义。读完这篇文章你可以学到什么: 空间中2d包围盒的概念 (boundingBox) 包围盒如何判断是否相交 多个包围盒如何如何联合一个大包围盒的 这就是为什么我要去分享这道题的原因,因为无论在3d或者2d中,你去判断「两个图形是否相交其实快速判断」 就是通过包围盒去做判断, 在游戏中你🤔一下,「一个游戏人物如何判断他是否走到墙壁了」。他是怎么实现碰撞的对吧, 游戏对象 都有一个「精灵」 和 「碰撞
从一道hard的leetcode到2d包围盒算法
|
人工智能 算法 机器人
亮风台2D AR算法新突破,夺冠世界权威评测 | ICRA 2108
亮风台提出的基于约束置信度的鲁棒跟踪算法(CCM),提高了在局部遮挡、光照变化和运动模糊等各种因素干扰情况下的鲁棒性。
498 0
|
18天前
|
算法 数据安全/隐私保护 计算机视觉
基于二维CS-SCHT变换和LABS方法的水印嵌入和提取算法matlab仿真
该内容包括一个算法的运行展示和详细步骤,使用了MATLAB2022a。算法涉及水印嵌入和提取,利用LAB色彩空间可能用于隐藏水印。水印通过二维CS-SCHT变换、低频系数处理和特定解码策略来提取。代码段展示了水印置乱、图像处理(如噪声、旋转、剪切等攻击)以及水印的逆置乱和提取过程。最后,计算并保存了比特率,用于评估水印的稳健性。
|
3天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于DCT变换和位平面分解的数字水印嵌入提取算法matlab仿真
这是一个关于数字水印算法的摘要:使用MATLAB2022a实现,结合DCT和位平面分解技术。算法先通过DCT变换将图像转至频域,随后利用位平面分解嵌入水印,确保在图像处理后仍能提取。核心程序包括水印嵌入和提取,以及性能分析部分,通过PSNR和NC指标评估水印在不同噪声条件下的鲁棒性。
|
4天前
|
算法 数据安全/隐私保护 C++
基于二维CS-SCHT变换和扩频方法的彩色图像水印嵌入和提取算法matlab仿真
该内容是关于一个图像水印算法的描述。在MATLAB2022a中运行,算法包括水印的嵌入和提取。首先,RGB图像转换为YUV格式,然后水印通过特定规则嵌入到Y分量中,并经过Arnold置乱增强安全性。水印提取时,经过逆过程恢复,使用了二维CS-SCHT变换和噪声对比度(NC)计算来评估水印的鲁棒性。代码中展示了从RGB到YUV的转换、水印嵌入、JPEG压缩攻击模拟以及水印提取的步骤。
|
5天前
|
机器学习/深度学习 算法 数据可视化
基于BP神经网络的32QAM解调算法matlab性能仿真
```markdown - 32QAM解调算法运用BP神经网络在matlab2022a中实现,适应复杂通信环境。 - 网络结构含输入、隐藏和输出层,利用梯度下降法优化,以交叉熵损失最小化为目标训练。 - 训练后,解调通过前向传播完成,提高在噪声和干扰中的数据恢复能力。 ``` 请注意,由于字符限制,部分详细信息(如具体图示和详细步骤)未能在摘要中包含。
|
6天前
|
机器学习/深度学习 算法 网络架构
基于yolov2深度学习网络的单人口罩佩戴检测和人脸定位算法matlab仿真
摘要:该内容展示了一个基于YOLOv2的单人口罩佩戴检测和人脸定位算法的应用。使用MATLAB2022A,YOLOv2通过Darknet-19网络和锚框技术检测图像中的口罩佩戴情况。核心代码段展示了如何处理图像,检测人脸并标注口罩区域。程序会实时显示检测结果,等待一段时间以优化显示流畅性。
|
9天前
|
机器学习/深度学习 算法
m基于GA-GRU遗传优化门控循环单元网络的电力负荷数据预测算法matlab仿真
在MATLAB 2022a中,一个基于遗传算法优化的GRU网络展示显著优化效果。优化前后的电力负荷预测图表显示了改进的预测准确性和效率。GRU,作为RNN的一种形式,解决了长期依赖问题,而遗传算法用于优化其超参数,如学习率和隐藏层单元数。核心MATLAB程序执行超过30分钟,通过迭代和适应度评估寻找最佳超参数,最终构建优化的GRU模型进行负荷预测,结果显示预测误差和模型性能的提升。
26 4
|
9天前
|
机器学习/深度学习 算法 数据可视化
基于BP神经网络的16QAM解调算法matlab性能仿真
这是一个关于使用MATLAB2022a实现的16QAM解调算法的摘要。该算法基于BP神经网络,利用其非线性映射和学习能力从复数信号中估计16QAM符号,具有良好的抗噪性能。算法包括训练和测试两个阶段,通过反向传播调整网络参数以减小输出误差。核心程序涉及数据加载、可视化以及神经网络训练,评估指标为误码率(BER)和符号错误率(SER)。代码中还包含了星座图的绘制和训练曲线的展示。
|
11天前
|
机器学习/深度学习 算法
基于BP神经网络的QPSK解调算法matlab性能仿真
该文介绍了使用MATLAB2022a实现的QPSK信号BP神经网络解调算法。QPSK调制信号在复杂信道环境下受到干扰,BP网络能适应性地补偿失真,降低误码率。核心程序涉及数据分割、网络训练及性能评估,最终通过星座图和误码率曲线展示结果。