Github 项目 - CPN 多人姿态估计

Github 项目 - tf-cpn
论文 - Cascaded Pyramid Network for Multi-Person Pose Estimation

CPN (Cascaded Pyramid Network) 是 COCO 2017 Keypoints 竞赛冠军方法,这里是基于 Tensorflow 的实现的多人姿态识别.
原始实现基于 Face++ (Megvii Inc) 内部深度学习框架(MegBrain) 的实现.

论文阅读 - Cascaded Pyramid Network for Multi-Person Pose Estimation - AIUAI

1. 实现结果

1.1. COCO minival dataset(Single Model)

测试代码需要基于人体检测器.

对于 COCO minival dataset,所采用的人体检测器的精度为 AP=41.1,其中关于人体的精度为 AP=55.3.

MethodBase ModelInput SizeAP @0.5:0.95AP @0.5AP @0.75AP mediumAP large
CPNResNet-50256x19269.788.377.066.276.1
CPNResNet-50384x28872.389.178.868.479.1
CPNResNet-101384x28872.989.279.469.179.9

1.2. COCO test-dev dataset (Single Model)

采用强检测器,对于 COCO test-dev dataset,其精度为 AP=44.5,其中关于人体的精度为 AP=57.2.

MethodAP @0.5:0.95AP @0.5AP @0.75AP mediumAP large
Detectron(Mask R-CNN)67.088.073.162.275.6
CPN(ResNet-101, 384x288)72.090.479.568.378.6

为了进行参考对比,采用 MegDet 的检测器,其精度为 AP=52.1,其中关于人体的检测精度为 AP=62.9,得到的姿态估计结果为:

MethodAP @0.5:0.95AP @0.5AP @0.75AP mediumAP large
MegDet+CPN(ResNet-101, 384x288)73.091.880.869.178.7

MegDet: A Large Mini-Batch Object Detector

2. 实现过程

2.1 MSCOCO 数据集上模型训练

[1] - 克隆项目

git clone https://github.com/chenyilun95/tf-cpn.git

假设本地项目路径为 $CPN_ROOT.

[2] - MSCOCO 图片数据 - http://cocodataset.org/#download. 在 COCO trainvalminusminival 数据集(googledrive) 上训练模型,并在 COCO minival 数据集(googledrive) 上验证模型.
下载的数据集和 Python API 放在路径 $CPN_ROOT/data/COCO/MSCOCO 中.
config.py 定义了所有路径,可以自定义设置.

[3] - 下载 base 模型(ResNet) 权重文件 - tf slim model_zoo,放于路径 $CPN_ROOT/data/imagenet_weights/.

[4] - 设置环境

pip3 install -r requirement.txt
cd $CPN_ROOT/lib
make clean; make all
cd $CPN_ROOT/lib/lib_kernal/lib_nms
./compile.sh

避免出现错误:from lib_kernel.lib_nms.gpu_nms import gpu_nms ImportError: libcudart.so.8.0: cannot open shared object.

[5] - 训练 CPN 模型,采用模型文件夹中的 network.py.

python3 network.py -d 0-1

模型训练后,输出路径 $CPN_ROOT/log/ 中包含的文件类似如下:

log/
|-model_dump/
|    |snapshot_1.ckpt.data-00000-of-00001
|    |snapshot_1.ckpt.index
|    |snapshot_1.ckpt.meta
|    |...
|train_logs.txt

2.2 COCO 数据集上模型验证

运行测试代码:

python3 mptest.py -d 0-1 -r 350

其中,这里假设存在训练 350 epochs 的模型文件.

如果需要指定预训练的模型路径,则可以运行:

python3 mptest.py -d 0-1 -m log/model_dump/snapshot_350.ckpt

提供的测试模型(googledrive):

人体 boxes 检测模型:

CPN 预训练模型:

3. 图片测试 Demo

测试文件路径内所有图片.
每张图片只简单进行 resize 到网络输入尺寸,未做翻转.

    import os
    import numpy as np
    import argparse
    from config import cfg
    import cv2
    import sys
    import matplotlib.pyplot as plt

    import tensorflow as tf

    from tfflat.base import Tester
    from tfflat.utils import mem_info
    from network import Network

    def analyse(tester, imagefile):
        test_img = cv2.imread(imagefile)
        # test_img = cv2.resize(test_img, (288, 384), interpolation=cv2.INTER_LINEAR)
        height, width, _ = test_img.shape
        scale_height = 384/height
        scale_width = 288/width
        scale_img = cv2.resize(test_img, (0, 0), fx=scale_width, fy=scale_height, interpolation=cv2.INTER_LANCZOS4)

        mean_img = scale_img - cfg.pixel_means
        mean_img = mean_img / 255.
        mean_img = mean_img.transpose(2, 0, 1)
        mean_img = np.asarray(mean_img).astype(np.float32)
        feed = np.zeros((1, mean_img.shape[0], mean_img.shape[1], mean_img.shape[2]))
        feed[0] = mean_img

        res = tester.predict_one([feed.transpose(0, 2, 3, 1).astype(np.float32)])[0]
        res = res.transpose(0, 3, 1, 2)[0]

        cls_skeleton = np.zeros((cfg.nr_skeleton, 3))
        res /= 255.
        res += 0.5
        for w in range(cfg.nr_skeleton):
            res[w] /= np.amax(res[w])
        border = 10
        dr = np.zeros((cfg.nr_skeleton, cfg.output_shape[0] + 2 * border, cfg.output_shape[1] + 2 * border))
        dr[:, border:-border, border:-border] = res[:cfg.nr_skeleton].copy()
        for w in range(cfg.nr_skeleton):
            dr[w] = cv2.GaussianBlur(dr[w], (21, 21), 0)
        for w in range(cfg.nr_skeleton):
            lb = dr[w].argmax()
            y, x = np.unravel_index(lb, dr[w].shape)
            dr[w, y, x] = 0
            lb = dr[w].argmax()
            py, px = np.unravel_index(lb, dr[w].shape)
            y -= border
            x -= border
            py -= border + y
            px -= border + x
            ln = (px ** 2 + py ** 2) ** 0.5
            delta = 0.25
            if ln > 1e-3:
                x += delta * px / ln
                y += delta * py / ln
            x = max(0, min(x, cfg.output_shape[1] - 1))
            y = max(0, min(y, cfg.output_shape[0] - 1))
            cls_skeleton[w, :2] = (x * 4 + 2, y * 4 + 2)
            cls_skeleton[w, 2] = res[w, int(round(y) + 1e-10), int(round(x) + 1e-10)]

        # map back to original images
        plt.imshow(test_img[:,:,::-1])
        for idx in range(cfg.nr_skeleton):
            plt.scatter(cls_skeleton[idx][0] / scale_width, cls_skeleton[idx][1]/scale_height, marker='p', color='r', s=10)
        plt.show()

    if __name__ == '__main__':

        gpu_ids = str(np.argmin(mem_info()))
        test_model = 'tf-cpn/models/COCO.res50.384x288.CPN/snapshot_350.ckpt'

        cfg.set_args(gpu_ids.split(',')[0])
        tester = Tester(Network(), cfg)
        tester.load_weights(test_model)

        images_list = os.listdir('/path/to/test_images')
        for image_file in images_list:
            image_file = os.path.join('/path/to/test_images', image_file)
            analyse(tester, image_file)

        print('Done.')

PyTorch CPN 实现

Last modification:April 17th, 2019 at 10:16 am

31 comments

  1. rain699

    请问训练时CPU占用率太高,达到300%。怎么解决呢?

    1. AIHGF
      @rain699

      是计算溢出了吗?我暂时还没遇到过.

  2. duan

    博主您好!请教下您一个问题,我在训练COCO.res50.256x192.CPN 过程中发现一个问题,开始starting training...之后,CPU占用率一直在上升,可能会崩掉。我尝试在config中将dpflow_enable 置为False,但是重新训练仍然是CPU一直上升,无法正常训练的问题,请问下您训练的时候也这样吗?怎样做一下处理?非常希望您能够指点一下!谢谢!

    1. rain699
      @duan

      我也遇到了这个情况,请问您解决了吗?

  3. colin

    你好,我想问一下这个网络处理单张图片的速度大概是多少(在GPU下)。

    1. AIHGF
      @colin

      以前在 980Ti 上测过速度,现在有点记不得了.

  4. 大公鸡

    请问博主对于人体检测是怎么做的?我用的FPN先检测人体框,然后送入CPN,结果发现如果框的质量不好会很影响CPN的结果;对于一些密集的场景或者是发生变形的体态,FPN检测的人体框可能会与其他框重合,这样送入CPN的crop内容可能不止一个人体,这种情况如何处理呢?

    1. AIHGF
      @大公鸡

      two-stages 的多人姿态估计,一般都会收到人体检测器的影响,如果是重叠的多人姿态估计,可能确实不好解决. alphapose 好像有关于 crowd 的部分.

      1. 大公鸡
        @AIHGF

        AlphaPose还没试过,OpenPose的效果我觉得可以接受,速度精度都还行,但是文章说Top-Bottom的方式在精度上是要比Bottom-Top好的,感觉只是在keypoints上的检测好一些,涉及多人情况还是要看Bottom-Top的,AlphaPose我去试一下

        1. AIHGF
          @大公鸡

          这个可能要根据应用场景具体情况具体分析.

  5. 糖三匙

    hello~能请问一下图片测试Demo中的第61行是什么意思嘛?我直接粘贴代码到python会报错呢?

    1. AIHGF
      @糖三匙

      已修改.

  6. xiang

    您遇到过,ImportError:Building module pycocotools_mask failed:["distutils.errors.CompileError: command 'gcc' failed with exit status 1n"]的错误吗?

    1. AIHGF
      @xiang

      没遇到过,可能是 pycocotools api 没正确安装.

  7. xiang

    您好,我将下载的train2014放入data/COCO/MSCOCO中,一直是read no image,是我的路径不对吗?

    1. LC
      @xiang

      你好,我也遇到了这个问题,我想问问你有解决了?

    2. AIHGF
      @xiang

      有没有确认下 image 文件是否存在?

      1. xiang
        @AIHGF

        方便加下您的微信或qq吗?

        1. AIHGF
          @xiang

          qq:2258922522

      2. xiang
        @AIHGF

        image不是下载的train2014文件吗?

        1. AIHGF
          @xiang

          可以尝试下单步运行,定位错误位置及原因.

        2. xiang
          @xiang

          PythonAPI我如果放在MSCOCO文件夹下的话,怎么会出现我刚刚说的importError呀?

          1. knight
            @xiang

            你好 我也出现了同样的问题,想问你解决了吗?

  8. zhepherd

    tfflat 是是什么?

    1. AIHGF
  9. luan

    谢谢,已经解决了

    1. 小银是猪
      @luan

      你是怎么解决的呢?我也发现了这个问题。

  10. luan

    您好?请问用的python3还是python2啊?functools32只能用于python2.7,希望看到后能够回复,谢谢

    1. AIHGF
      @luan

      我当时用的是 python3.

      1. luan
        @AIHGF

        感谢!可是functools32怎么安装的呢?我使用python3.6尝试了下,pip functools32时,说它只适用于python2.7

        1. AIHGF
          @luan

          functool32 安装?代码里应该是有 from functools import partial,但未遇到你说的问题. 具体点呢?

Leave a Comment