Amazon SageMakerと画像認識のための深層学習ツールキットGluonCVによる人の姿勢推定

人の姿勢を推定したい

今カメラに写っている人は何人いるのか、それぞれどっちを向いているのか、どの手が上がっているのか、どの足が前にあるのか等、画像や映像から人の姿勢を知りたいことはありませんでしょうか。座っているのか、倒れているのか、後ろを向いているのかわかることで、様々なビジネスに応用できるのではと思っています。そこで、今回は、Amazon SageMakerと画像認識のための深層学習ツールキットGluonCVを用いた、人の姿勢を推定したいと思います。

Gluonとは

Gluonは、MicrosoftとAWSが公開した、深層学習向けのライブラリやツールキットです。Apacheライセンスで公開されていて、サンプルが多数公開されています。その中でも、GluonCVは、画像認識周りのライブラリが公開されています。GluonCVの主なライブラリとして、画像分類、オブジェクト検出、画像セグメンテーション、姿勢推定などがあります。

基本的なセットアップ

それでは早速、姿勢推定するための準備として、基本的なセットアップについてご紹介したいと思います。まずはじめにSageMakerの画面を開きます。

次にノートプックインスタンスを作成します。

学習済みモデルを使って推論するだけですので、t3.largeインスタンスを指定しました。

しばらく待つと「In Service」となり、使用できる状態となります。

ここで、ノートブックインスタンスのJupiter Notebookを開きます。「Open Jupiter」

新しくスクリプトを実行しますので、右上のメニューボタンから「New」を選択して、「conda_mxnet_p36」を選択します。

ここから先はスクリプトの入力です。

必要なライブラリ関係をアップグレードします。コマンドを貼り付けたらShift+Enterで実行します。

!pip install --upgrade pip
!pip install --upgrade mxnet gluoncv

これで準備OKです。

姿勢推定のサンプルを実行する

続きまして、姿勢推定のサンプルを実行します。

必要なライブラリをインポートします。

from matplotlib import pyplot as plt
from gluoncv import model_zoo, data, utils
from gluoncv.data.transforms.pose import detector_to_simple_pose, heatmap_to_coord

使用する学習モデルを指定します。今回は、Yolo3とResNetです。

detector = model_zoo.get_model('yolo3_mobilenet1.0_coco', pretrained=True)
pose_net = model_zoo.get_model('simple_pose_resnet18_v1b', pretrained=True)

検出するのは「人」です。

detector.reset_class(["person"], reuse_weights=['person'])

GitHubで公開されているサッカーの画像を指定してダウンロードします。オリジナル画像を指定したい場合には、ここのURLを変更してください。

im_fname = utils.download('https://github.com/dmlc/web-data/blob/master/' +
                          'gluoncv/pose/soccer.png?raw=true',
                          path='soccer.png')

姿勢推定します。

x, img = data.transforms.presets.ssd.load_test(im_fname, short=512)
class_IDs, scores, bounding_boxs = detector(x)

pose_input, upscale_bbox = detector_to_simple_pose(img, class_IDs, scores, bounding_boxs)

predicted_heatmap = pose_net(pose_input)
pred_coords, confidence = heatmap_to_coord(predicted_heatmap, upscale_bbox)

推定結果を画像に書き込んで、画面に表示します。

plt.rcParams['figure.figsize'] = (15.0, 15.0)
ax = utils.viz.plot_keypoints(img, pred_coords, confidence,
                              class_IDs, bounding_boxs, scores,
                              box_thresh=0.5, keypoint_thresh=0.2)
plt.show()

以下は実行結果です。画像から人を検出して姿勢が先で表現されていますね。

人の姿勢だけにフォーカスして出力してみましょう

from matplotlib import pyplot as plt
from gluoncv import model_zoo, data, utils
from gluoncv.data.transforms.pose import detector_to_simple_pose, heatmap_to_coord

detector = model_zoo.get_model('yolo3_mobilenet1.0_coco', pretrained=True)
pose_net = model_zoo.get_model('simple_pose_resnet18_v1b', pretrained=True)

detector.reset_class(["person"], reuse_weights=['person'])

plt.rcParams['figure.figsize'] = (15.0, 15.0)

im_fname = 'biking.jpg'
x, img = data.transforms.presets.ssd.load_test(im_fname, short=512)
print('Shape of pre-processed image:', x.shape)

class_IDs, scores, bounding_boxs = detector(x)

pose_input, upscale_bbox = detector_to_simple_pose(img, class_IDs, scores, bounding_boxs)

predicted_heatmap = pose_net(pose_input)
pred_coords, confidence = heatmap_to_coord(predicted_heatmap, upscale_bbox)

import numpy as np
bg = np.zeros(img.shape)

ax = utils.viz.plot_keypoints(bg, pred_coords, confidence,
                              class_IDs, bounding_boxs, scores,
                              box_thresh=1, keypoint_thresh=0.2)
plt.show()

実行にすると以下のような結果になります。

まとめ

これでサッカー選手の位置や姿勢が取れますね。例えば、オリジナルの学習モデルとしてサッカーボールを認識するようにして、その位置を検出できれば、どの選手がボールをキープし続けているのか、パスを出しているのか、受け取っているのか、歩いているか、走っているか、倒れているかなど様々なデータを自動で収集できそうですね。事前に選手の顔画像も登録しておけば、誰かもわかってしまいます。このように、様々なコミュニティで公開済みの学習済みモデルと、自分で作成したオリジナルの学習モデルを用いて、画像や映像に写っている出来事を推論することができるようになります。また、今回はSageMaker上で実行しましたが、Nvidia JetsonやRaspberry Piなどでも実行できると思いますので、エッジ側の処理を多彩に高速に実行できそうですね。

参考資料