stMind

about Tech, Computer vision and Machine learning

openposeのjsonを解析する

昨日は、ナチョがウェストブロム戦で見せた奇跡のクリアをopenposeで関節推定してみました。openposeは、関節位置をファイル出力するオプションを用意しているので、jsonで出力して黒背景に関節位置を描画しましたが、その時の解析手順を簡単にまとめておきます。

jsonファイル出力

openpose実行時にwrite_keypoint_jsonを指定します。

$ ./build/examples/openpose/openpose.bin --image_dir ~/data/nacho --write_keypoint_json ~/data/results

ファイルの中身はこんな感じ。pose_keypointsが関節位置で、people以下に検出した人数分が出力されます。

{
        "version":1.0,
        "people":[
        {
            "pose_keypoints":[
                247.668,514.465,0.89905,247.702,527.27,0.87725,236.549,527.306,0.878132,233.307,541.693,0.918291,236.415,544.831,0.709778,258.863,527.235,0.795694,263.66,540.037,0.772329,269.998,554.436,0.744358,246.054,556.101,0.807442,246.055,575.247,0.484067,0,0,0,258.864,556.007,0.797664,260.464,573.657,0.435004,266.807,583.267,0.163514,246.067,511.293,0.856283,249.24,509.715,0.886759,241.254,514.496,0.671889,250.916,514.453,0.700287
            ],
            "face_keypoints":[
                
            ],
            "hand_left_keypoints":[
                
            ],
            "hand_right_keypoints":[
                
            ]
        }
    ]
}

pose_keypointsは(x座標, y座標, 信頼度) x 関節数18で、54個の値が含まれています。それから、関節位置の順番ですが、 openpose/poseParameters.hpp at master · CMU-Perceptual-Computing-Lab/openpose · GitHubに定義された通り(POSE_COCO_BODY_PARTS)になっていて、backgroundは関節位置には含まれませんので注意。さらに、関節位置の結合順序は、POSE_COCO_PAIRSに定義されてます。親切。

pythonjsonをパース

pythonは3.6.1です。シンプルにやると、

  • jsonをload
  • 検出された人数分のループ
    • 関節の全ペアのループ
    • ペアをcv2.lineで描画

たまに関節位置が求められなくて信頼度0.0になっているところだけ注意する必要があります。

import json
import numpy as np
import cv2

# jsonのロード
with open('nacho_0_keypoints.json', 'r') as f:
    data = json.load(f)

# 黒背景画像の用意
img_ = cv2.imread('original.jpg')
img = np.zeros_like(img_)

# 関節毎の描画色
colors = [(255.,     0.,    85.), (255.,     0.,     0.), (255.,    85.,     0.), (255.,   170.,     0.), (255.,   255.,     0.), (170.,   255.,     0.), (85.,   255.,     0.), (0.,   255.,     0.), (0.,   255.,    85.), (0.,   255.,   170.), (0.,   255.,   255.), (0.,   170.,   255.), (0.,    85.,   255.), (0.,     0.,   255.), (255.,     0.,   170.), (170.,     0.,   255.), (255.,     0.,   255.), (85.,     0.,   255.)]

# 検出された全員について
for d in data['people']:
     kpt = np.array(d['pose_keypoints']).reshape((18, 3))
     # 関節位置の全ペアについて
     for p in pairs:
         pt1 = tuple(list(map(int, kpt[p[0], 0:2])))
         c1 = kpt[p[0], 2]
         pt2 = tuple(list(map(int, kpt[p[1], 0:2])))
         c2 = kpt[p[1], 2]
         # 信頼度0.0の関節は無視
         if c1 == 0.0 or c2 == 0.0:
             continue
         # 関節の描画
         color = tuple(list(map(int, colors[p[0]])))
         img = cv2.line(img, pt1, pt2, color, 7)

cv2.imshow('nacho', img)

参照

以上のことは、下記を参照しています。

github.com