PR

Kinectで手の動きに合わせてモニタ上の画像を動かすサンプル

2012年7月23日(月)
薬師寺 国安

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックして、リスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

Option Strict On
Imports Microsoft.Kinect
Imports Coding4Fun.Kinect.Wpf

Class MainWindow
  Dim newSensor As KinectSensor

  Dim no As Integer = 0
  Dim myFlag As Boolean

ウィンドウが読み込まれた時の処理

Skeletonクラス型の変数firstを宣言しておきます。
KinectSensorChooser1.KinectSensorChangedイベントで、Kinectが接続されているどうかを確認します。古いセンサーが動いている時は停止させ、新しいセンサーを取得します。
パラメータのスムージング変換を行う、新しいTransformSmoothParameters型のインスタンスmyParamオブジェクトを作成します。各プロパティの値を設定します。
Smoothingでは、スムージングの量を設定します。値は0から1.0の範囲で、規定値は0.5です。値が大きいほど平滑化されますが、処理時間は増加します。
Correctionでは、平滑化の緩急を付けます。値は0から1.0の範囲で、規定値は0.5です。1.0に近いほど処理時間は早くなります。
Predictionでは、スムーズに動作させるため予測されたフレームの数を設定します。
JitterRadiusでは、ジッタ低減の半径(メートル)を設定します。デフォルトは0.05(5cm)です。
MaxDeviationRadiusでは、フィルタされた値と生データとの誤差の許容最大値を設定します。単位はメートルで、規定値は0.04(4cm)です。
上記のプロパティを設定したmyParamオブジェクトを、SkeletonStreamのEnableメソッドに指定して、スケルトン・トラッキング(プレイヤーの認識)を有効にします。
ColorStream.EnableメソッドでKinectセンサーのRGBカメラの機能を有効にします。ColorImageFormat.RgbResolution640x480Fps30列挙体で「RGBフォーマットで、解像度は640×480、フレームレートは毎秒30フレーム」と設定します。
DepthStream.Enableメソッドで距離カメラの機能を有効にします。「解像度は 320 × 240、フレーム レートは 毎秒30フレーム」と設定します。
RGBカメラ、距離カメラ、骨格のフレーム更新イベントである、AllFramesReadyにイベントハンドラを指定します。スケルトンストリームを開き、円が左手、右手の動きに反応する、SensorSkeletonReadyプロシージャを実行します。その際に、RGBカメラ、距離カメラ、スケルトンフレームの更新を同時に行う、AllFramesReadyイベント時に渡されるAllFramesReadyEventArgsを渡します。
フレームごとのスケルトンデータを表すクラスである、SkeletonFrame型のskeletonFrameData変数を宣言し、e.OpenSkeletonFrameメソッドで、新しいフレームでのスケルトンの情報を取得します。
スケルトン配列の長さを取得するSkeletonArrayLengthプロパティで初期化された、新しいSkeletonクラス型の配列変数allSkeletonsを宣言します。
CopySkeletonDataToメソッドで、フレームのスケルトンデータを取得します。引数として、SkeletonArrayLength分の長さが確保されたSkeletonの配列を渡します。つまり、現在のSkeletonFrameDataにあるスケルトンデータを、指定した配列(allSkeletons)にコピーするということです。
CopySkeletonDataToメソッドで取得されるデータは、プレイヤー分取得されるため、それぞれのトラッキング状態を確認します。
Skeletonクラス用オブジェクト変数firstで、スケルトンデータを持つallSkeletons配列変数内で、全ての関節の位置がトラッキングされた状態にある、先頭の要素を取得していきます。
次に、Image1とトラッキング状態にある、左手、右手のジョイントの情報を引数にScalePositionプロシージャを実行します。次に、スケルトンの位置を取得するGetCameraPointプロシージャを実行します。
Kinectセンサーを開始します。例外が発生した場合はエラーを表示して処理を抜けます。

    Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
      myRotate.Angle = 0
      Dim first As Skeleton
  
      AddHandler KinectSensorChooser1.KinectSensorChanged, Sub(kinectSender As Object, kinectArgs As DependencyPropertyChangedEventArgs)
        Dim oldSensor As KinectSensor = DirectCast(kinectArgs.OldValue, KinectSensor)
        StopKinect(oldSensor)
        newSensor = DirectCast(kinectArgs.NewValue, KinectSensor)
        If newSensor Is Nothing = True Then
            Return
        End If
        Dim myParam As New TransformSmoothParameters
        With myParam
          .Smoothing = 0.7F 
          .Correction = 0.3F 
          .Prediction = 0.4F
          .JitterRadius = 1.0F。
          .MaxDeviationRadius = 0.5F 
        End With
 
    With newSensor
      .SkeletonStream.Enable(myParam)
      .ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30)
      .DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30)
    End With
 
    AddHandler newSensor.AllFramesReady, Sub(frameSender As Object, frameArgs As AllFramesReadyEventArgs)
    SensorSkeletonReady(frameArgs)
  
      Using skeletonFrameData As SkeletonFrame = frameArgs.OpenSkeletonFrame() 
        Dim allSkeletons As Skeleton() = New Skeleton(skeletonFrameData.SkeletonArrayLength - 1) {}        skeletonFrameData.CopySkeletonDataTo(allSkeletons)        first = (From s In allSkeletons Where s.TrackingState = SkeletonTrackingState.Tracked Select s).FirstOrDefault()
      End Using
  
        If first Is Nothing Then
          Return
        End I
        ScalePosition(Image1, first.Joints(JointType.HandLeft))
        ScalePosition(Image1, first.Joints(JointType.HandRight))
        GetCameraPoint(first, frameArgs)
            End Sub
 
      Try
            newSensor.Start()
      Catch ex As Exception
            MessageBox.Show(ex.Message)
            Exit Sub
      End Try
        End Sub
    End Sub

スケルトンストリームを開き、円が左手、右手の操作によって動作する処理

フレームごとのスケルトンデータを表すクラスである、SkeletonFrame型のmySkeleton変数を宣言し、e.OpenSkeletonFrameメソッドで、スケルトンのフレーム情報を取得します。これらのメソッドで取得するSkeletonFrameは、Usingで括るか、明示的にDisposeする必要があります。
スケルトン配列の長さを取得するSkeletonArrayLengthプロパティで初期化された、新しいSkeletonクラス型の配列変数skeletonDataを宣言します。CopySkeletonDataToメソッドで、現在のSkeletonFrameにあるスケルトンデータを、指定した配列(skeletonData)にコピーします。CopySkeletonDataToメソッドで取得されるデータはプレイヤー分取得されるため、それぞれのトラッキング状態を確認します。
Skeletonクラス用オブジェクト変数dataを宣言し、スケルトンデータを持つskeletonData配列変数内で、全ての関節の位置がトラッキングされた状態にある、先頭の要素を取得します。要素が取得された場合は、左手、右手の動きで円が動作するSetEllipsePositionプロシージャを実行します。

    Private Sub SensorSkeletonReady(e As AllFramesReadyEventArgs)
      Using mySkeleton As SkeletonFrame = e.OpenSkeletonFrame
        If mySkeleton Is Nothing = True Then
          Return
        End If
        Dim skeletonData As Skeleton() = New Skeleton(mySkeleton.SkeletonArrayLength - 1) {}
        mySkeleton.CopySkeletonDataTo(skeletonData)
        Dim data As Skeleton = (From s In skeletonData Where s.TrackingState = SkeletonTrackingState.Tracked).FirstOrDefault()
        If data Is Nothing = False Then
          SetEllipsePosition(HandLeft, data.Joints(JointType.HandLeft))
          SetEllipsePosition(HandRight, data.Joints(JointType.HandRight))
        End If
      End Using
    End Sub
薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています