Kinectで手の動きとカーソルを連動して操作するサンプル(3ページ目)
前ページからの続きです。
スケルトンのフレーム更新を行い、手の動きでマウスカーソルを操作する処理
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
今回のサンプルは以上で終了です。右手と左手を使った操作に慣れるのが少し難しいですが、未来的なインターフェイスを体験できるかと思います。
それでは、次回もお楽しみに。