memorandums

日々の生活で問題解決したこと、知ってよかったことなどを自分が思い出すために記録しています。

Kinectで腕(手)のスイング速度を計ってみた

昨日、MBAKinectの開発環境をセットアップしなおしたので、遊びがてら手の移動速度を計ってみました。

環境は、Processingでsimple-openniを使用しています。

simple-openniのサンプルにスケルトンの端点の3次元位置を取得できるものがあるので、それを利用しただけです。。。使ったサンプルはexamples/OpenNI/Userです。

実装上のポイントは以下です。といっても新しい情報はありませんが。。。


■方法

(1)時間差の計測にProcessingのmillis()を利用。今回値を保存して、前回値と今回値の差を取得します。こちらの単位はその名の通りミリ秒です。

(2)3次元位置の計測はSimpleOpenNIのgetJointPositionSkeletonメソッドで取得します。PVectorで取得できます。一応、SimpleOpenNIのgetJointPositionSkeletonメソッドの戻り値がconfidenceをあらわしているようですので、この値が0.6以上(数値は適当)のときの値を利用します。ちなみに単位はmmです。

(3)上記の(2)で取得した3次元位置も、(1)の時間差の計算と同様に、今回値を保存して、前回値と今回値の差をProcessingのdist関数で単位時間あたりの移動距離を求めます。

(4)最後に、(3)の移動距離を(1)の時間差で割ると手の移動速度(mm/ms)が求められます。


■実験

腕を降って最高スピードを表示してみました。思いっきり手を降って20(mm/ms)くらいの数値が出ました。


■検証

腕の振り速度の代表値がないものかとネットを検索してみましたが見つからず。あったのはゴルフやバットのスイング速度です。で、ちょっと考えてみたのですが、例えば100km/hでボールを投げられるとすれば手の速度もそれと同じ(もしくはそれより高い)はずです。
ということで上記の実験結果をkm/hにしますと、20(mm/ms) ÷(1,000,000 ÷ (60 x 60 x 1,000))=72 (km/h)となります。一応、Googleの検索窓で「20 mm/ms in km/h」と入れても同じ結果になりましたので間違いないでしょう。

結構、いい値だと思いません(笑)?


■余談

ある程度、いい値が出ますので、外れ値の処理をそれなりにやれば使い物になりそうです。例えば、パンチ力を測定する体感ゲームなんかありましたね?あんなのもすぐにつくれそう。Kinectポーズをとらないといけないのは難ですが。ひさしぶりにKinectで遊んでちょっとした発見でした。

ちなみにやりたいことはバレーボールの腕のスイング速度の測定です。もちろん、腕の振りだけではなくスナップも必要だと思いますが、とりあえずフォームの管理や能力向上のための測定などに応用できたらな。。。と思います。ただ、現場レベルで普及するには野球やゴルフのスピードガンのようなコンポーネントにならないと、いちいちコードにPC持っていってKinectを設置して。。。ではいかんですね。