OpenPose のDNN部分をChainer CPUで動かしてみた

More than 1 year has passed since last update.

こちらの記事は当方blogからの転載になります。


はじめに

今回はMacで、OpenPoseをchainerを使って実行してみます。

(全体ではなく検出ヒートマップを生成する一部の機能になります)

1. Caffeの学習済みモデルをダウンロードする

2. ChainerからCaffeのモデルを読み込む

3. Chainerのネットワークに画像を適用する

CVPR2017で発表された単眼カメラによる骨格推定アルゴリズムのOpenPose、すでにUbuntu, Windowsでのリアルタイムな処理が実現することが報告されています。ですがGPUが必要だったりMacは対応してなかったりなので、どうにかMac やCPUでも動かせないかと思い、CaffeのモデルをChainerで読み込んで前半のDNNの部分だけ実行してみます。


実行環境 (Linuxでも動くはず)

Mac book Pro (2.7 GHz Intel Core i5,16 GB 1867 MHz DDR3)

Python2.7 (Chainer, Numpy)


作業

1. Caffeの学習済みモデルをダウンロードする

こちらにWindows向けの実行バイナリがあるのでダウンロードします。この中にCaffeのパラメータファイルが含まれています。

(直リンクが気になる方は https://github.com/CMU-Perceptual-Computing-Lab/openpose/blob/master/doc/installation.md の中程にあるDownload and unzip the portable OpenPose demo 1.0.1.から落としてください)

2. ChainerからCaffeのモデルを読み込む

今回は、骨格18点を推定するCOCOモデルを使用します。(MPIモデルも同様の手順で可能)

Caffeのモデルが以下のディレクトリに保存されています。

OpenPose_demo_1.0.1/models/pose/coco/pose_iter_440000.caffemodel

これをchainerから読み込みます。

from chainer.functions import caffe

func = caffe.CaffeFunction('pose_iter_440000.caffemodel')

3. Chainerのネットワークに画像を適用する

OpenPose_demo_1.0.1/models/pose/coco/pose_deploy_linevec.prototxt

を読むとネットワークの構成が書かれており、最後の出力層をみてみると

layer {

name: "concat_stage7"
type: "Concat"
bottom: "Mconv7_stage6_L2"
bottom: "Mconv7_stage6_L1"
# top: "concat_stage7"
top: "net_output"
concat_param {
axis: 1
}
}

となっており、出力ノードの1つ目はMconv7_stage6_L2 という名前で定義されています。

(Mconv7_stage6_L1の方はボーンっぽい)

というわけで、これをfuncの出力層に指定することで(1,19,h,w)の出力マップを得ることができます。

x = chainer.Variable([画像のnumpy配列])

y, = func(inputs={'data': x}, outputs=['Mconv7_stage6_L2'])
print y.data.shape #(1,19,h,w)

画像のnumpy配列は、サイズが(1, 4, height, width) で値が0〜255ではなく0.0〜1.0

さらにdtypeがnp.float32になっていないといけないことに注意してください。

(RGBではなくRGBAが想定されているのか分かりませんが、4番目には0を埋めて入力しています)

↓試してみたのがこちらの画像

paku2-200x300.jpg

testout-768x228.png

    POSE_COCO_BODY_PARTS {

{0, "Nose"},
{1, "Neck"},
{2, "RShoulder"},
{3, "RElbow"},
{4, "RWrist"},
{5, "LShoulder"},
{6, "LElbow"},
{7, "LWrist"},
{8, "RHip"},
{9, "RKnee"},
{10, "RAnkle"},
{11, "LHip"},
{12, "LKnee"},
{13, "LAnkle"},
{14, "REye"},
{15, "LEye"},
{16, "REar"},
{17, "LEar"},
{18, "Bkg"},
}

ヒートマップは上の構造体に書かれた体の部位のそれぞれの存在確率を示しています。

1枚あたり10秒ぐらいかかりますが、CPUでも動くので使い道が広がりそうです。