Kinectで手の動きとカーソルを連動して操作するサンプル
前ページからの続きです。
スケルトンのフレーム更新を行い、手の動きでマウスカーソルを操作する処理
e.OpenSkeletonFrameメソッドで、新しいフレームのスケルトン情報を取得します。このメソッドで取得するskeletonFrameは、Usingで括るか、明示的にDisposeする必要があります。
SkeletonFrameクラスは、フレームごとのスケルトンデータを表すクラスです。
スケルトンの配列の長さ分(skeletonFrameData.SkeletonArrayLength - 1)のSkeletonクラス型の配列変数skeletonArrayを宣言します。Skeletonクラスはプレイヤーごとのスケルトン情報を表すクラスです。
CopySkeletonDataToメソッドは、現在の SkeletonFrameにある、スケルトンのデータを指定した配列にコピーします。
これで取得されるデータはプレイヤー分取得されますので、各プレイヤーのトラッキング状態を確認します。
プレイヤーごとのスケルトン情報をもつ、skeletonArray配列変数内を、繰り返し変数skeletonDataで反復処理しながら以下の処理を繰り返します。
SkeletonTrackingState.Trackedで全ての関節の位置がトラッキングされ、左手や右手がトラッキングされている場合は、スケルトンの座標データ持つJointクラス型のjointRightとjointLeft変数を宣言し、Jointsプロパティで右手と左手の関節部分を取得します。
同様にJointクラス型のscaleRightとscaleLeft変数を宣言します。
ScaleToメソッドに、プライマリ ディスプレイ モニターの画面の幅(ピクセル単位)を示す値と、プライマリ ディスプレイ モニターの画面の高さ(ピクセル単位)を示す値を指定します。
また、定数メンバ変数として宣言しておいたSkeletonMaxXとSkeletonMaxYの値も指定して、指定した最大幅と最大高さに、Jointオブジェクトの位置をスケーリングします。
ScaleToメソッドの書式は下記の通りです。このScaleToメソッドはCoding4Fun.Kinect.Toolkitに含まれるメソッドです。
Joint.ScaleTo(width As Integer, height As Integer, maxSkeletonX As Float, maxSkeletonY As Float)
Fix関数は小数部分を取り除いた整数値を返す関数です。スケーリングされた値は、それぞれscaleRightとscaleLeft変数に格納しておきます。
変数cursorXに右手のX座標の位置を、cursorYには右手のY座標の位置を格納します。
右手のY座標の位置が33cmより大きく、または左手のY座標の位置が33cmより大きくなければ(つまり、左手が下におろされている場合)は、ブール型変数leftClickの値をTrue(ホールドされた状態)にし、そうでない場合は(左手が上に挙げられている場合)False(ホールドが解除)で初期化します。
SendMouseInputメソッドで、右手の動きに合わせてカーソルを制御し、左手の上げ下げで現在のカーソル位置でのホールドと解除を実現します。SendMouseInputはCursorClass.dllに含まれています。書式は下記の通りです。
SendMouseInput(ByVal positionX As Integer, ByVal positionY As Integer, ByVal maxX As Integer, ByVal maxY As Integer, ByVal leftDown As Boolean)
positionXには右手のX座標の位置、positionYには右手のY座標の位置、maxXにはプライマリ ディスプレイ モニターの画面の幅(ピクセル単位)を示す値、maxYにはプライマリ ディスプレイ モニターの画面の高さ(ピクセル単位)を示す値、leftDownには左手の動きによって判別されるブール型変数leftClickの値を指定します。
Private Sub SensorSkeletonReady(e As AllFramesReadyEventArgs) Using skeletonFrameData As SkeletonFrame = e.OpenSkeletonFrame If skeletonFrameData Is Nothing = True Then Return End If Dim skeletonArray(skeletonFrameData.SkeletonArrayLength - 1) As Skeleton skeletonFrameData.CopySkeletonDataTo(skeletonArray) For Each skeletonData In skeletonArray If skeletonData.TrackingState = SkeletonTrackingState.Tracked Then If skeletonData.Joints(JointType.HandLeft).TrackingState = JointTrackingState.Tracked AndAlso skeletonData.Joints(JointType.HandRight).TrackingState = JointTrackingState.Tracked Then Dim cursorX As Integer Dim cursorY As Integer Dim jointRight As Joint = skeletonData.Joints(JointType.HandRight) Dim jointLeft As Joint = skeletonData.Joints(JointType.HandLeft) Dim scaledRight As Joint = jointRight.ScaleTo(CInt(Fix(SystemParameters.PrimaryScreenWidth)), CInt(Fix(SystemParameters.PrimaryScreenHeight)), SkeletonMaxX, SkeletonMaxY) Dim scaledLeft As Joint = jointLeft.ScaleTo(CInt(Fix(SystemParameters.PrimaryScreenWidth)), CInt(Fix(SystemParameters.PrimaryScreenHeight)), SkeletonMaxX, SkeletonMaxY) cursorX = CInt(Fix(scaledRight.Position.X)) cursorY = CInt(Fix(scaledRight.Position.Y)) Dim leftClick As Boolean If jointRight.Position.Y > ClickThreshold OrElse (Not jointLeft.Position.Y > ClickThreshold) Then leftClick = True Else leftClick = False End If KinectCursor.SendMouseInput(cursorX, cursorY, CInt(Fix(SystemParameters.PrimaryScreenWidth)), CInt(Fix(SystemParameters.PrimaryScreenHeight)), leftClick) Return End If End If Next End Using End Sub
RGBカメラを有効にしてカメラの画像を表示する
Image1という名前を持つImageコントロールのSourceプロパティに、e.OpenColorImageFrameメソッドで、新しいフレームのRGBカメラ情報を取得し、Coding4Fun.Kinect.Wpfの拡張メソッドであるToBitmapSourceで、colorFrameをBitmapSourceに変換して指定します。
このメソッドで取得するColorImageFrameは、Usingで括るか、明示的にDisposeする必要があります。
Private Sub SensorColorFrameReady(e As AllFramesReadyEventArgs) Using colorFrame As ColorImageFrame = e.OpenColorImageFrame If colorFrame Is Nothing = True Then Return End If Image1.Source = colorFrame.ToBitmapSource End Using End Sub
Kinect センサーの動作を停止する処理
Kinectセンサーが動作している場合は、動作を停止し、リソースを解放します。
Private Sub StopKinect(ByVal sensor As KinectSensor) If sensor Is Nothing = False Then If sensor.IsRunning = True Then sensor.Stop() sensor.Dispose() End If End If End Sub
ウィンドウが閉じられた時の処理
動作しているKinectセンサーを引数に、Kinectセンサーの動作を停止する、StopKinectプロシージャを実行します。
Private Sub MainWindow_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing StopKinect(newSensor) End Sub End Class
今回のサンプルは以上で終了です。右手と左手を使った操作に慣れるのが少し難しいですが、未来的なインターフェイスを体験できるかと思います。
それでは、次回もお楽しみに。
Kinectで手の動きに合わせてカーソルを動かすサンプル
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Kinectで手の動きに合わせてモニタ上の画像を動かすサンプル
- Kinectで人体を認識して棒人間を動かすサンプル
- Kinectを使って、顔の動きを認識して画面に表示する
- センサーの範囲内にいる人間を見つけて撮影・保存するKinectサンプル
- Kinectを使って、自分の手のひらに小さな分身を出現させてみる
- 声で選んだアイテムをプレイヤーの身体に装着・連動させるKinectサンプル
- Kinectを使ったバーチャル試着室で着せ替えシミュレーション
- Kinectで手の動きに合わせて波紋を発生させるサンプル
- 手を動かして画面上の写真を左右にスライドさせるKinectサンプル
- 人物特定に使える!?実際の映像で顔を認識するKinectプログラム