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 Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

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