DensePose-COCO / DensePose-PoseTrack データセットについて

本資料は、DensePose(densepose.org)が提供する DensePose-COCO および DensePose-PoseTrack データセットの概要、利用条件、確認方法、および学習済みモデルによる推定(推論)の実行方法についてまとめたものです。

1. DensePose とは

DensePose は、RGB画像に写る人物のすべてのピクセルを、人体表面を表す3次元サーフェスモデル(SMPLモデル)上の座標に対応付ける(マッピングする)ための手法およびデータセットです。 Rıza Alp Güler、Natalia Neverova、Iasonas Kokkinos らにより提案され、2018年のCVPRで発表されました。

この対応付けを学習させるために構築されたのが DensePose-COCO データセットであり、COCOデータセットの画像のうち約5万枚に、人物領域と3Dモデル表面との対応関係が人手でアノテーションされています。

2. データセットのダウンロード

2.1 DensePose-COCO

DensePose-COCO のアノテーション(JSON形式)は、DensePoseリポジトリのインストール手順内で案内されているダウンロードリンクから取得します。 画像本体はアノテーションには含まれず、COCOデータセットの公式ダウンロードページから train2014val2014 を別途取得する必要があります。

学習・評価に用いる主なデータ分割は以下の3種類です。

分割名用途
train2014学習用
valminusminival2014学習用(検証セットを除いた残り)
minival2014検証用

2.2 DensePose-PoseTrack

DensePose-PoseTrack は、複数人物が映る動画像シーケンスにアノテーションを付与したデータセットで、 急激な動き・オクルージョン(隠れ)・スケール変化を含む、より難易度の高い対応推定タスクを想定しています。 画像本体は PoseTrack公式サイト の案内に従って取得し、アノテーション自体はDensePoseリポジトリの案内するリンクから取得します。 主な分割は posetrack_train2017(学習用)と posetrack_val2017(検証用)です。

利用条件について: DensePose-COCO および DensePose-PoseTrack の両データセットは、非営利目的での利用に限定される Creative Commons NonCommercial ライセンスの下で配布されています。 研究・商用を問わず利用に先立ち、配布元が定める最新の利用規約・ライセンス条件を必ず各自でご確認ください。

3. アノテーションの内容

DensePose-COCO / DensePose-PoseTrack のアノテーションは、人体表面をパーツ単位に分割した「チャートベース」表現を基本としており、以下のフィールドで構成されます。

DensePose-COCOには、これに加えて3Dモデル上の頂点に直接対応付ける「連続表面埋め込み(Continuous Surface Embeddings)」形式のアノテーションも用意されており、 dp_x, dp_y, dp_vertex, ref_model のフィールドで表現されます。

アノテーションはCOCOアノテーション形式に準拠しているため、pycocotools を用いて直接読み込み・操作することができます。

4. 画像と3次元モデルの確認

DensePoseリポジトリには、アノテーションおよび3Dモデルとの対応関係を可視化するためのJupyterノートブックが公式に用意されています。

5. 2次元画像から3次元モデルの推定(推論)

学習済みのDensePose-RCNNモデルを用いることで、入力画像中の人物ピクセルを3Dモデル表面座標へ対応付ける推論を実行できます。 以下は、公式リポジトリのツール tools/infer_simple.py を用いた実行例です。 1枚の画像、または指定した拡張子を持つ画像を含むフォルダを入力として受け取り、可視化結果をPDF、 IUV画像(*_IUV.png)、インスタンス分割画像(*_INDS.png)として出力ディレクトリに保存します。

5.1 コマンドライン実行例

python2 tools/infer_simple.py \
    --cfg configs/DensePose_ResNet101_FPN_s1x-e2e.yaml \
    --output-dir /root/data/infer_out/ \
    --image-ext png \
    --wts https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl \
    /root/data/frame
本リポジトリはCaffe2ベースであり Python 2 系での実行を前提としています。現在は後継である Detectron2版DensePose に開発が引き継がれており、最新の環境で利用する場合はそちらのツールを使用することが推奨されています。

5.2 推論スクリプトの内容(Python)

上記コマンドが呼び出す tools/infer_simple.py の処理内容は、次のように構成されています。 指定フォルダ内の画像を1枚ずつ読み込み、学習済みモデルで人物検出・パーツ分割・キーポイント推定・DensePose推定(IUV座標推定)を行い、 その可視化結果を出力ディレクトリに保存する、という一連の流れです。

from collections import defaultdict
import argparse
import cv2  # NOQA (Must import before importing caffe2 due to bug in cv2)
import glob
import logging
import os
import sys
import time

from caffe2.python import workspace

from detectron.core.config import assert_and_infer_cfg
from detectron.core.config import cfg
from detectron.core.config import merge_cfg_from_file
from detectron.utils.io import cache_url
from detectron.utils.logging import setup_logging
from detectron.utils.timer import Timer
import detectron.core.test_engine as infer_engine
import detectron.datasets.dummy_datasets as dummy_datasets
import detectron.utils.c2 as c2_utils
import detectron.utils.vis as vis_utils

c2_utils.import_detectron_ops()

# OpenCL may be enabled by default in OpenCV3; disable it because it's not
# thread safe and causes unwanted GPU memory allocations.
cv2.ocl.setUseOpenCL(False)

parser = argparse.ArgumentParser(description='End-to-end inference')
parser.add_argument(
    '--cfg',
    dest='cfg',
    help='cfg model file (/path/to/model_config.yaml)',
    default=None,
    type=str
)
parser.add_argument(
    '--wts',
    dest='weights',
    help='weights model file (/path/to/model_weights.pkl)',
    default=None,
    type=str
)
parser.add_argument(
    '--output-dir',
    dest='output_dir',
    help='directory for visualization pdfs (default: /tmp/infer_simple)',
    default='/tmp/infer_simple',
    type=str
)
parser.add_argument(
    '--image-ext',
    dest='image_ext',
    help='image file name extension (default: jpg)',
    default='jpg',
    type=str
)
parser.add_argument(
    'im_or_folder', help='image or folder of images', default=None
)
args = parser.parse_args()

workspace.GlobalInit(['caffe2', '--caffe2_log_level=0'])
setup_logging(__name__)
logger = logging.getLogger(__name__)

merge_cfg_from_file(args.cfg)
cfg.NUM_GPUS = 1
args.weights = cache_url(args.weights, cfg.DOWNLOAD_CACHE)
assert_and_infer_cfg(cache_urls=False)
model = infer_engine.initialize_model_from_cfg(args.weights)
dummy_coco_dataset = dummy_datasets.get_coco_dataset()

if os.path.isdir(args.im_or_folder):
    im_list = glob.iglob(args.im_or_folder + '/*.' + args.image_ext)
else:
    im_list = [args.im_or_folder]

for i, im_name in enumerate(im_list):
    out_name = os.path.join(
        args.output_dir, '{}'.format(os.path.basename(im_name) + '.pdf')
    )
    logger.info('Processing {} -> {}'.format(im_name, out_name))

    im = cv2.imread(im_name)
    timers = defaultdict(Timer)
    t = time.time()
    with c2_utils.NamedCudaScope(0):
        cls_boxes, cls_segms, cls_keyps, cls_bodys = infer_engine.im_detect_all(
            model, im, None, timers=timers
        )
    logger.info('Inference time: {:.3f}s'.format(time.time() - t))
    for k, v in timers.items():
        logger.info(' | {}: {:.3f}s'.format(k, v.average_time))
    if i == 0:
        logger.info(
            ' \ Note: inference on the first image will be slower than the '
            'rest (caches and auto-tuning need to warm up)'
        )

    vis_utils.vis_one_image(
        im[:, :, ::-1],  # BGR -> RGB for visualization
        im_name,
        args.output_dir,
        cls_boxes,
        cls_segms,
        cls_keyps,
        cls_bodys,
        dataset=dummy_coco_dataset,
        box_alpha=0.3,
        show_class=True,
        thresh=0.7,
        kp_thresh=2
    )

元の実装にあった parse_args() 関数および main() 関数、および if __name__ == '__main__': によるエントリポイント分岐は、 本スクリプトが単一の実行スクリプトとして直接呼び出されることを前提に、トップレベルの逐次処理へ統合しています。 引数解析(argparse)・モデル初期化・推論・可視化という処理内容および実行順序、各関数呼び出しの引数は元の実装から変更していません。

5.3 出力される可視化結果の確認

--output-dir に指定したディレクトリには、入力画像1枚につき次の3種類のファイルが生成されます。

これらの出力ファイルは、前述のDensePose-RCNN-Visualize-Results.ipynbノートブックを用いて可視化・確認することができます。