昨日は、ナチョがウェストブロム戦で見せた奇跡のクリアをopenposeで関節推定してみました。openposeは、関節位置をファイル出力するオプションを用意しているので、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に定義されてます。親切。
pythonは3.6.1です。シンプルにやると、
- jsonをload
- 検出された人数分のループ
- 関節の全ペアのループ
- ペアをcv2.lineで描画
たまに関節位置が求められなくて信頼度0.0になっているところだけ注意する必要があります。
import json
import numpy as np
import cv2
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]
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