Kinectで切るモーションを判定するin development

 
date:2013.11.09   posted by:saito
 
mca work from home

p>こんにちは、まりもです。

Samuration」について技術的な側面から全3回に渡って解説しています。

内訳はこちら。
1. Mindwaveで脳波を取得する
2. ArduinoでLEDを脳波に合わせて光らせる
3. Kinectで竹を切るモーションを判定する

今日は前回のブログで掲載した「2. ArduinoでLEDを脳波に合わせて光らせる」の続き、
3. Kinectで竹を切るモーションを判定する
を解説したいと思います。

■Kinectとは
Kinectとは、骨格表示や深度などを取ることができるゲームデバイスのことです。
for windowsとXboxバージョンがあります。詳しいスペックはKinect for Windows公式サイトをご覧下さい。

■実装
実装する上で、やってみよう!Kinectアプリ開発のコードを参考にし、改変しました。
リアルタイムでジェスチャーをとっているのは右手首(WristRight)ですが、ジェスチャー判定をしているのは右手首と左手首(WristLeft)を使っています。
右手首でのジェスチャー判定の場合、Spine+15cmの高さより右手首が高くSpineより右手首が右側にあればフラグ1をたて、Spine+15cmの高さより右手首が低くSpineより右手首が左側にあればフラグ2をたてています。
左手首での場合では、Spine+15cmの高さより左手首が高くSpineより左手首が左側にあればフラグ1をたて、Spine+15cmの高さより左手首が低くSpineより左手首が右側にあればフラグ2をたてています。
また、古い右手首の位置情報を保存しているのは、刀の切った方向と距離を算出するためです。

以下のようにコードを書きました。言語はC#です。


//Spine+15cmの高さより右手首が高くSpineより右手首が右側にあればフラグをたてる
if ((spine.Position.Y + 0.15 < rwrist.Position.Y) && (spine.Position.X < rwrist.Position.X))
{
  if (humanNum == selectedId)
  {
    //右手首の位置を保存しておく
    prevSkeleton = skeleton;
    prevWrist = prevSkeleton.Joints[JointType.WristRight];
    prevSpine = prevSkeleton.Joints[JointType.Spine];
    prevwristPt = kinect.CoordinateMapper.MapSkeletonPointToColorPoint(prevWrist.Position, rgbFormat);
    prevwristPos = new System.Windows.Point(prevwristPt.X, prevwristPt.Y);
      return 1;
    }
    else return 0;
  }
//Spine+15cmの高さより左手首が高くSpineより左手首が左側にあればフラグをたてる
else if ((spine.Position.Y + 0.15 < lwrist.Position.Y) && (spine.Position.X > lwrist.Position.X))
{
  if (humanNum == selectedId)
  {
    //右手首の位置を保存しておく
    prevSkeleton = skeleton;
    prevWrist = prevSkeleton.Joints[JointType.WristLeft];
    prevSpine = prevSkeleton.Joints[JointType.Spine];
    prevwristPt = kinect.CoordinateMapper.MapSkeletonPointToColorPoint(prevWrist.Position, rgbFormat);
    prevwristPos = new System.Windows.Point(prevwristPt.X, prevwristPt.Y);
    return 1;
  }
  else return 0;

}
//Spine+15cmの高さより右手首が低くSpineより右手首が左側にあればフラグをたてる
else if ((rwrist.Position.Y < spine.Position.Y + 0.15) && (spine.Position.X > rwrist.Position.X))
{
  if (humanNum == selectedId && prevWrist.Position.X > prevSpine.Position.X) return 2;
  else return 0;
}
//Spine+15cmの高さより左手首が低くSpineより左手首が右側にあればフラグをたてる
else if ((lwrist.Position.Y < spine.Position.Y + 0.15) && (spine.Position.X < lwrist.Position.X))
{
  if (humanNum == selectedId && prevWrist.Position.X < prevSpine.Position.X) return 2;
  else return 0;
}
return 0;

今回、中心にいる人だけSkeletonを判定させる、という処理もしました。
スクリーン横軸の中心とSpineとの距離を測り、中心に近いSkeletonだけを判定させるものです。
以下がコードになります。


//中心にいるSpineの判定
//640であるかどうかは解像度によって違うので確認して下さい
if (distance > Math.Abs(skeletonPos[humanNum, 0] - 640 / 2))
{
  distance = Math.Abs(skeletonPos[humanNum, 0] - 640 / 2);
  selectedId = humanNum;
}

skeletonPos[humanNum, 0] はPoint変換されたSpineのXの値です。

いかがでしたでしょうか。
Samurationは作っていて大変でもありましたが、楽しく作る事が出来、自分自身成長できたという実感があります。
これからも色々なデバイスに挑戦していきたいです。
ここまでご覧下さり、ありがとうございました!

 
Copyright © TheDesignium inc. powered by WordPress & mootools.
Relative Keyword|none