Kinectで手の動きに合わせてモニタ上の画像を動かすサンプル
次に、ソリューションエクスプローラー内の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
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Kinectで人体を認識して棒人間を動かすサンプル
- Kinectを使って、自分の手のひらに小さな分身を出現させてみる
- Kinectで手の動きに合わせて波紋を発生させるサンプル
- 声で選んだアイテムをプレイヤーの身体に装着・連動させるKinectサンプル
- Kinectで手の動きとカーソルを連動して操作するサンプル
- プレイヤーの身体パーツを判別するKinectサンプル
- Kinectを使って、顔の動きを認識して画面に表示する
- Kinectで得た人体情報を転送して、Windows Phoneの画面上に関節の位置を表示してみる
- Kinectを使ったバーチャル試着室で着せ替えシミュレーション
- 人体の連続した動作を音声でキャプチャするKinectのサンプルプログラム