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データセットの公式ダウンロードページから
train2014、val2014 を別途取得する必要があります。
学習・評価に用いる主なデータ分割は以下の3種類です。
| 分割名 | 用途 |
|---|---|
train2014 | 学習用 |
valminusminival2014 | 学習用(検証セットを除いた残り) |
minival2014 | 検証用 |
2.2 DensePose-PoseTrack
DensePose-PoseTrack は、複数人物が映る動画像シーケンスにアノテーションを付与したデータセットで、
急激な動き・オクルージョン(隠れ)・スケール変化を含む、より難易度の高い対応推定タスクを想定しています。
画像本体は
PoseTrack公式サイト
の案内に従って取得し、アノテーション自体はDensePoseリポジトリの案内するリンクから取得します。
主な分割は posetrack_train2017(学習用)と posetrack_val2017(検証用)です。
3. アノテーションの内容
DensePose-COCO / DensePose-PoseTrack のアノテーションは、人体表面をパーツ単位に分割した「チャートベース」表現を基本としており、以下のフィールドで構成されます。
dp_x,dp_y:アノテーション点の画像上の座標dp_I:どの身体パーツ(インデックス)に属するかを示す値dp_U,dp_V:パーツ内でのUV座標(表面上の位置)dp_masks:14パーツに粗く分割したセグメンテーション情報
DensePose-COCOには、これに加えて3Dモデル上の頂点に直接対応付ける「連続表面埋め込み(Continuous Surface Embeddings)」形式のアノテーションも用意されており、
dp_x, dp_y, dp_vertex, ref_model のフィールドで表現されます。
アノテーションはCOCOアノテーション形式に準拠しているため、pycocotools を用いて直接読み込み・操作することができます。
4. 画像と3次元モデルの確認
DensePoseリポジトリには、アノテーションおよび3Dモデルとの対応関係を可視化するためのJupyterノートブックが公式に用意されています。
notebooks/DensePose-COCO-Visualize.ipynb:COCO画像上にDensePose-COCOのアノテーションを重畳表示して確認するnotebooks/DensePose-COCO-on-SMPL.ipynb:アノテーションを3D参照モデル(SMPL)上に配置し、UVマッピングとの対応を確認するPoseTrack/DensePose-PoseTrack-Visualize.ipynb:DensePose-PoseTrackのアノテーションを画像シーケンス上で確認する
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
--cfg:モデル構成を定義するYAML設定ファイルへのパス--wts:学習済み重みファイル(.pkl)のURLまたはパス。URL指定時は自動的にダウンロード・キャッシュされる--output-dir:可視化結果(PDF、IUV画像、INDS画像)の出力先ディレクトリ--image-ext:入力フォルダを指定した場合に対象とする画像の拡張子(省略時jpg)- 末尾の位置引数:入力画像1枚へのパス、または画像フォルダへのパス
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種類のファイルが生成されます。
<元のファイル名>.pdf:検出された人物のバウンディングボックス、セグメンテーション、キーポイント、DensePose推定結果を重畳した可視化画像<元のファイル名>_IUV.png:推定されたパーツインデックス(I)およびUV座標(U, V)を格納した画像<元のファイル名>_INDS.png:検出されたインスタンスごとの領域を示すセグメンテーション画像
これらの出力ファイルは、前述のDensePose-RCNN-Visualize-Results.ipynbノートブックを用いて可視化・確認することができます。