Translate

【matplotlib】human pose estimationのデータからmatplotlibでスティックピクチャ(棒人間)を描画する方法【python】

 こんにちは

よく理学療法士や作業療法士といったリハビリテーション関連職種の研究での発表資料では、身体の各関節の座標データをスティックピクチャ(棒人間)のように描画していることがあると思います。

あの技術は一見難しいのかなと思われがちですが、pythonのグラフ描画機能であるmatplotlibの機能を駆使することで意外と簡単に作ることができます。

本記事では、pythonの拡張パッケージであるmatplotlibを用いてスティックピクチャを作成する方法について紹介していこうと思います。

matplotlibでスティックピクチャを描画するのには散布図と折れ線グラフを使う。


matplotlibと一ついってもいろんなグラフの描画機能があります。その中でもスティックピクチャを描画するために必要となるのは散布図と折れ線グラフになります。

散布図は各関節の位置座標そのものを表現し、折れ線グラフは各関節の位置座標をつなぐ役割になっております。

基本的な散布図の書き方や、折れ線グラフの書き方については、過去の記事でも紹介しているので、matplotlibの基礎的な部分が苦手な方についてはそちらの記事も併せてみておくことをお勧めします。


基本的には散布図は通常通りに使える。

関節位置そのものを表現する際には、matplotlibのscatter関数を使用します。この関数は引数としてx座標、y座標を入力することでその座標にマルをプロットするという処理になります。

つまり特定の関節の座標のXY座標がわかっていればその座標をこの関数を使ってプロットすればよいということになります。

具体的にはこんな感じになります。

import numpy as np
import matplotlib.pyplot as plt

#今回用にnumpyで作ったサンプルデータ(このaとかbの部分を自身のデータに置き換える)
shoulder = data#ここは各個人の座標データを入れてください。今回はXYの二次元配列座標を想定します。
#1フレーム目の座標を表示する場合
#matplotlibの設定
fig = plt.figure(figsize = (5,5))
ax = fig.add_subplot(111)
ax.scatter(shoulder[:,0],shoulder[:,1])

今回は肩関節の位置座標を想定してコードを作成しました。
関節位置が一つの場合にはこのような書き方になります。普段通りに散布図の描画になるので、これ単体では簡単だと思います。

関節位置をつなぐ場合にはplot関数を使う。

各関節の位置座標を表示するだけであれば、さっきの散布図のプロットだけで目的は達成できます。しかしながら散布図だけのスティックピクチャというのは、関節の位置関係がわかりにくく見にくいのが現状です。

各関節を線でつなぐことにより視認性を上げることができます。この処理にはmatplotlibでいうところのplot関数を使用します。

実際のコード例を紹介します。今回は肩関節と肘関節をつなぐことを想定します。

import numpy as np
import matplotlib.pyplot as plt

#今回用にnumpyで作ったサンプルデータ(このaとかbの部分を自身のデータに置き換える)
shoulder = data#ここは各個人の座標データを入れてください。今回はXYの二次元配列座標を想定します。
elbow = data2 #肘の仮想データ※ここは肩と同様に自分自身のデータを入れてください。
#1フレーム目の座標を表示する場合
#matplotlibの設定
fig = plt.figure(figsize = (5,5))
ax = fig.add_subplot(111)
#散布図のプロット
ax.scatter(shoulder[0,0],shoulder[0,1])
ax.scatter(elbaw[0,0],elbow[0,1])
#線で結ぶプロット
ax.plot([[shoulder[0,0],elbaw[0,0]],[shoulder[0,1],elbaw[0,1]]])

重要になるのは一番最後の行です。カッコが複数で分かりにくいですが、具体的にはこのような感じでカッコで囲んで、X座標、Y座標それぞれに対して、始点および終点を割り当て入るという感じになります。

今回のコードでは実際のデータやダミーデータは用意していないので、ご自身のデータで試してみてもられるといいでしょう。

グラフのアスペクト比は要注意

スティックピクチャを描画する際に注意しないといけない点としては、表示するグラフのアスペクト比(縦横比)をしっかりと統一する必要があります。これが狂っていると縦や横に間延びしたようなスティックピクチャになってしまいます。

一番良いのはax.set_xlim(○○,○○)、ax.set_ylim(○○,○○)で値の描画範囲を設定してしまうのが手っ取り早いです。重要なのは、この範囲がXとYの値の範囲が一致していることが前提条件になります。