やってみよう!Kinectアプリ開発 - 第4回 骨格情報の利用

2012-06-22 17:18

おまけ(関節の向きの利用)

今回はついでにv1.5で追加された関節の向きの利用も紹介します。背景に上書きするマスク画像を頭の向きによって変形させてみましょう。

コードビハインドの修正

処理の修正は以下の3点です。

  • 頭の方向の取得
    頭部の位置を取得する際に、方向も一緒に取得して保存しておきます。修正は以下の通りです。
  • マスク画像の変形
    取得した頭部の向きを基にマスク画像を変形します。修正は以下の通りです。

    この修正のポイントは以下の通りです。
    • 頭部の向きをX・Y平面上に射影(M11, M12, M21, M22)する。
    • 骨格の座標系と画面の座標系はY軸の向きが逆なので反転する。
    • PushTransformで渡す変換は原点(0,0)を中心とする変換なので、DrawImageは原点を中心として描画し、MatrixTransformの方に、頭部位置(headPt.X, headPt.Y)への移動を加える。
  • 呼び出し側の修正
    getHeadPointsとfillBitmapの2つのメソッドの引数の型を変えたので、それらを呼び出すAllFrameReadyメソッドも合わせて修正します。

実行

以上で修正は完了です。これまでと同様に、メニューから[デバッグ(D)]-[デバッグ実行(S)]を選択し、実行してみましょう。

さらに怖くなった気もしますが、頭を傾けるとそれに応じてマスク画像が回転するようになりました。

まとめ

前回のカメラの利用に続き、今回は骨格情報の利用を紹介しました。次回は深度情報の利用方法を紹介します。

商標について

Kinect、Visual C#、Visual Studio、Windowsは、米国Microsoft Corporationの米国およびその他の国における登録商標または商標です。

4件の質問スレッド
  • バージョンアップで? kazgb 2012-10-31 22:05 SDKがバージョンアップされて、
    警告みたいなのがでていたので気になりました。

    >= kinect.MapSkeletonPointToColor(headPos, rgbFormat);

    大雑把でアレですが上の部分。。。
    一応動くみたい?ですが、[使用しないでください]と記述されていました。

    調べて、以下に書き換えました。

    = kinect.CoordinateMapper.MapSkeletonPointToColorPoint(headPos, rgbFormat);

    動いているので問題なさそうですが、、、大丈夫・・・ですよね? うん。
  • 解説のDrawingVisualについて claw 2012-08-09 17:03 はじめまして。
    現在、大学でプログラミングを学びはじめた者です。

    非常に細かいことで申し訳ないのですが、
    2ページ目、fillBitmapメソッドの解説の部分、

    > DrawingVisualのRenderOpenメソッドでDrawingContextオブジェクトを作成します。

    となっていますが、
    DrawingVisualのRenderOpenメソッドでDrawContextオブジェクトを作成します。
    の間違い(?)ではないでしょうか?

    読んでいて少し混乱してしまったので……
    1件のコメント
    • kinection.jp管理人 clawさん

      ご質問を理解できていないかも知れませんが、RenderOpenメソッドでDrawingContextクラスのオブジェクトを作成しているので、意図通りです(DrawContextというクラスはありません)。
      もし、用語として「<クラス名>オブジェクト」ではなく「<変数名>オブジェクト」とすべき、という意味であれば、例えばgoogleで"DrawingContext-object"で検索すれば普通に使われているのがわかると思います。
      2012-08-10 10:00
  • 保存について 柏木 2012-07-17 10:06 初めまして。
    初心者なのですが、取得した骨格情報というのはテキストなどに保存可能でしょうか?
    全20ポイントのスケルトンのx,y,z座標を30フレームで取得し続け、10分程度のデータを保存することは可能でしょうか?
    続いて、取得したRBG画像を動画として保存することは可能でしょうか?
    環境は
    VisualStudio2010でc#
    Kinect for Windows v.1.5
    Windows7
    です。

    よろしくお願いいたします。
    2件のコメント
    • 柏木 コメントありがとうございます!えと・・・そうなると、たとえば
      (1)
      void kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
      {
      try
      {
      using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
      {
      if (skeletonFrame != null)
      {
      DrawSkeleton(skeletonFrame);
      }
      }
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message);
      }
      }
      private void DrawSkeleton(SkeletonFrame skeletonFrame)
      {
      // スケルトンのデータを取得する
      Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
      skeletonFrame.CopySkeletonDataTo(skeletons);

      SkeletonCanvas.Children.Clear();

      // スケルトンのジョイントを一つ一つ取得
      foreach (Skeleton skeleton in skeletons)
      {
      // スケルトンがトラッキング状態の場合は、ジョイントを取得
      if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
      {
      // ジョイントを保存する
      foreach (Joint joint in skeleton.Joints)
      {
      // ジョイントがトラッキングされていなければ次へ
      if (joint.TrackingState == JointTrackingState.NotTracked)
      {
      continue;
      }

      // ジョイントの座標を保存する
      JointRecord(joint.Position);
      }
      }
      }
      }
      とでもして、JointRecord部分で・・・どう作ればいいのかわからなくなってしまっております。Console.WriteLineで保存可能なのでしょうか?

      (2)
      void kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
      {
      try
      {
      // RGBカメラのフレームデータを取得する
      using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
      {
      if (colorFrame != null)
      {
      // RGBカメラのピクセルデータを取得する
      byte[] colorPixel = new byte[colorFrame.PixelDataLength];
      colorFrame.CopyPixelDataTo(colorPixel);

      // ピクセルデータをビットマップに変換する
      RGBCameraImage.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
      PixelFormats.Bgr32, null, colorPixel, colorFrame.Width * colorFrame.BytesPerPixel);
      }
      }
      }
      catch (Exception ex)
      {
      MessageBox.Show(ex.Message);
      }
      }
      たとえばこの状態だとして、GridのImageを動画で保存するにはどのようにすればいいのでしょうか?

      色々検索はしてみたのですが、画像保存の場合くらいしか見つからず、よく分かりませんで。

      どうぞよろしくお願いいたします。
      2012-07-20 10:40
    • 初音玲 (1)
      保存先の書き込みスピードにもよりますがテキストデータとしての保存は可能です。

      (2)
      取得したRGB画像を動画として保存することは可能です。
      2012-07-19 02:19
  • バグ修正 kinection.jp管理人 2012-07-03 09:38 かおるんさんご指摘の画像が反転するバグの修正です。

    Matrix rot = new Matrix(-headMtrx.M11, headMtrx.M12,
    -headMtrx.M21, headMtrx.M22,
    headPt.X, headPt.Y);

    M11 と M12 のところの符号を反転させています。

ジグソープレミアムレビュー

  • やってみようKinect(キネクト)アプリ開発 - ラボクルー集まれ!