前ページからの続きです。
骨格と接合部分を描画する
DrawBoneメソッドで、「胴体」「左腕」「右腕」「左脚」「右脚」を描いていきます。
接合部分をJoint型の繰り返し変数myJointで反復処理しながら、以下の処理を行います。
接合部分が追跡されている場合は、Brushクラス型の変数drawBrushにメンバ変数[追跡された関節のブラシ]のブラシを指定します。
接合部分が推測されている場合は、メンバ変数推測された関節のブラシ(黄色)を指定します。DrawingContext.DrawEllipse メソッドで、指定した Brush および Pen を使用して楕円を描画します。書式は下記の通りです。
DrawingContext.DrawEllipse(楕円の塗りつぶしに使用するブラシ[これは省略可能であり、Nothing を指定できます], 楕円のストロークを描画する際に使用するペン[これは省略可能であり、Nothing を指定できます], 楕円の中心の位置, 楕円の横半径, 楕円の縦半径)
「楕円の塗りつぶしに使用するブラシ」には変数のdrawBrushの値を指定します。「楕円のストロークを描画する際に使用するペン」にはNothingを指定し、「楕円の中心の位置」には、スケルトンポイントを出力する、SkeletonPointToScreen関数の戻り値を指定します。
「楕円の横半径」と「楕円の縦半径」にはメンバ定数変数[関節の太さ]の3を指定します。
01 | Private Sub DrawBonesAndJoints(ByVal skeleton As Skeleton, ByVal drawingContext As DrawingContext) |
04 | DrawBone(skeleton, drawingContext, JointType.Head, JointType.ShoulderCenter) |
05 | DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderLeft) |
06 | DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, s) |
07 | DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.Spine) |
08 | DrawBone(skeleton, drawingContext, JointType.Spine, JointType.HipCenter) |
09 | DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipLeft) |
10 | DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipRight) |
13 | DrawBone(skeleton, drawingContext, JointType.ShoulderLeft, JointType.ElbowLeft) |
14 | DrawBone(skeleton, drawingContext, JointType.ElbowLeft, JointType.WristLeft) |
15 | DrawBone(skeleton, drawingContext, JointType.WristLeft, JointType.HandLeft) |
18 | DrawBone(skeleton, drawingContext, JointType.ShoulderRight, JointType.ElbowRight) |
19 | DrawBone(skeleton, drawingContext, JointType.ElbowRight, JointType.WristRight) |
20 | DrawBone(skeleton, drawingContext, JointType.WristRight, JointType.HandRight) |
23 | DrawBone(skeleton, drawingContext, JointType.HipLeft, JointType.KneeLeft) |
24 | DrawBone(skeleton, drawingContext, JointType.KneeLeft, JointType.AnkleLeft) |
25 | DrawBone(skeleton, drawingContext, JointType.AnkleLeft, JointType.FootLeft) |
28 | DrawBone(skeleton, drawingContext, JointType.HipRight, JointType.KneeRight) |
29 | DrawBone(skeleton, drawingContext, JointType.KneeRight, JointType.AnkleRight) |
30 | DrawBone(skeleton, drawingContext, JointType.AnkleRight, JointType.FootRight) |
32 | For Each myJoint As Joint In skeleton.Joints |
33 | Dim drawBrush As Brush = Nothing |
35 | If myJoint.TrackingState = JointTrackingState.Tracked Then |
36 | drawBrush = 追跡された関節のブラシ |
37 | ElseIf myJoint.TrackingState = JointTrackingState.Inferred Then |
38 | drawBrush = 推測された関節のブラシ |
41 | If drawBrush Is Nothing = False Then |
42 | drawingContext.DrawEllipse(drawBrush, Nothing, SkeletonPointToScreen(myJoint.Position), 関節の太さ, 関節の太さ) |
スケルトンポイントを出力する関数
距離カメラのX-Y座標データを表す、DepthImagePoint構造体の変数depthPointを宣言し、MapSkeletonPointToDepthメソッドで、スケルトンの座標を、距離カメラの座標に変換します。距離カメラの解像度は640×480で、1秒当たり30フレームとなります。
レンダー領域を制限し、距離カメラのxとy座標を戻り値とします。
01 | Private Function SkeletonPointToScreen(ByVal skelpoint As SkeletonPoint) As Point |
02 | Dim depthPoint As DepthImagePoint = newSensor.MapSkeletonPointToDepth(skelpoint, DepthImageFormat.Resolution640x480Fps30) |
03 | Dim x As Double = depthPoint.X |
04 | If x > ScreenWidth Then |
10 | Dim y As Double = depthPoint.Y |
11 | If y > ScreenHeight Then |
16 | Return New Point(x, y) |
骨格と接合部分を描画するメソッド
スケルトンの部位を特定する、Joint型の変数myJoint0を宣言します。同様にmyJoint1変数を宣言します。これらの関節のいずれかを見つけることができない場合は、終了します。両方のポイントが推論される場合は描画しません。
Penクラス型の変数drawPenを宣言し、メンバ変数[推測された骨のペン色と幅](Navyで幅10)で初期化しておきます。
両方の接合部位が追跡されている場合は、変数drawPenにメンバ変数[追跡された骨のペン色と幅](赤で幅6)で初期化します。
DrawingContext.DrawLine メソッドで、指定したPenを使用して、指定した Points の間の線を描画します。書式は下記の通りです。
DrawingContext.DrawLine(線のストロークを描画する際に使用するペン, 線の開始点, 線の終点)
「線のストロークを描画する際に使用するペン」にはPen型の変数drawPenを指定します。「線の開始点」と「線の終点」には、スケルトンポイントを出力する関数SkeletonPointToScreenに、引数として、それぞれの関節の位置を渡して取得できる、戻り値を指定します。
01 | Private Sub DrawBone(ByVal skeleton As Skeleton, ByVal drawingContext As DrawingContext, ByVal jointType0 As JointType, ByVal jointType1 As JointType) |
02 | Dim myJoint0 As Joint = skeleton.Joints(jointType0) |
03 | Dim myJoint1 As Joint = skeleton.Joints(jointType1) |
05 | If myJoint0.TrackingState = JointTrackingState.NotTracked OrElse myJoint1.TrackingState = JointTrackingState.NotTracked Then |
08 | If myJoint0.TrackingState = JointTrackingState.Inferred AndAlso myJoint1.TrackingState = JointTrackingState.Inferred Then |
12 | Dim drawPen As Pen = 推測された骨のペン色と幅 |
13 | If myJoint0.TrackingState = JointTrackingState.Tracked AndAlso myJoint1.TrackingState = JointTrackingState.Tracked Then |
14 | drawPen = 追跡された骨のペン色と幅 |
17 | drawingContext.DrawLine(drawPen, SkeletonPointToScreen(myJoint0.Position), SkeletonPointToScreen(myJoint1.Position)) |
Kinect センサーを停止する処理
Kinectセンサーが動作している場合は、イベントとイベント ハンドラの関連付けを解除します。Kinectセンサーの動作を停止し、リソースを解放します。
01 | Private Sub StopKinect(sensor As KinectSensor) |
02 | If sensor Is Nothing = False Then |
03 | If sensor.IsRunning = True Then |
04 | RemoveHandler sensor.SkeletonFrameReady, AddressOf SkeletonsReady |
今回のサンプルは以上で終了です。このサンプルを応用すれば、自分の動きにあわせてXboxのゲームのようにアバターが動くアプリが作れるかもしれませんね。棒人間が動くだけでも十分楽しいので、ぜひチャレンジしてみてください。
それでは、次回もお楽しみに。