こちらの記事は当方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を埋めて入力しています)
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でも動くので使い道が広がりそうです。