PR

Kinect v2のジェスチャーでBing Mapsを未来的に直感操作する

2015年1月14日(水)
薬師寺 国安

新しいボディフレームの準備ができているときに発生するイベント処理

リスト4:MainWindow.xaml.vbの一部 (リスト3の続き)

Private Sub myBodyFrameReader_FrameArrived(sender As Object, e As BodyFrameArrivedEventArgs)
    'CanvasBody.Children.Clear()
    Using myBodyFrame = e.FrameReference.AcquireFrame  (1)
        If myBodyFrame Is Nothing = True Then
            Return
        End If
        myBodyFrame.GetAndRefreshBodyData(myBodies)  (2)
    End Using
    CanvasBody.Children.Clear()   (3)
    For Each body In myBodies
        For Each joint In body.Joints   (4)
            If joint.Value.TrackingState = TrackingState.Tracked Then
                DrawEllipse(joint.Value, 10, Brushes.Transparent)   (5)
                If joint.Value.JointType = JointType.HandRight Then
                    If body.Joints(JointType.HandTipRight).TrackingState = TrackingState.Tracked Then
                        myColorSpacePoint = myKinect.CoordinateMapper.MapCameraPointToColorSpace(body.Joints(JointType.HandTipRight).Position)   (6)
                        myHandPositionX = CInt(myColorSpacePoint.X * 0.5) 'CInt((body.Joints(JointType.ThumbRight).Position.X))   (7)
                        myHandPositionY = CInt(myColorSpacePoint.Y * 0.5) 'CInt((body.Joints(JointType.ThumbRight).Position.Y))
                        DrawHandState(body.Joints(JointType.HandRight), body.HandRightState, body.HandRightConfidence)
                    End If
                End If
            End If
        Next
    Next
End Sub
  1. e.FrameReference.AcquireFrameメソッドで、ボディフレームを取得し、myBodyFrameで参照します。myBodyFrameに何もなかった場合は、何も行いません。
  2. GetAndRefreshBodyDataメソッドで、更新されたボディデータを取得します。
  3. CanvasBody内を一度クリアしておきます。
  4. ボディデータの中を、反復処理を行いながら、繰り返し変数jointで関節の位置を反復処理しながら、位置を取得していきます。
  5. 関節が追跡されている場合は、関節の位置と、関節の位置を描く円の大きさと描く色(透明)を指定して、DrawEllipseを実行します。
  6. 右手が追跡されている場合は、CoordinateMapper.MapCameraPointToColorSpaceメソッドで、関節の位置をカメラ空間から距離空間へのポイントにマップし、変数myColorSpacePointで参照します。
  7. 手のXとY軸の位置を取得して、メンバー変数、myHandPositionXとmyHandPositionYに格納します。右手の位置と、右手の状態と、右手を追跡している精度を引数にして、DrawHandStateを実行します。

プレイヤーの手の形によって条件分岐を行う処理

リスト5:MainWindow.xaml.vbの一部(リスト4の続き)

Private Sub DrawHandState(joint As Joint, state As HandState, myTrackingConfidence As TrackingConfidence)
    If myTrackingConfidence <> TrackingConfidence.High Then
        Return
    End If
    If state = HandState.Open Then   (1)
        Index = 1
    ElseIf state = HandState.Closed Then   (2)
        Index = 2
    Else    (3)
        Index = 3
    End If
End Sub
  1. 手がパーの状態なら、Indexの値を1で初期化します。
  2. 手がグーの状態の場合は、メンバー変数Indexを2で初期化します。
  3. それ以外は「3」で初期化します。

関節の位置に透明の円を表示する処理

リスト6:MainWindow.xaml.vbの一部(リスト5の続き)

Private Sub DrawEllipse(myJoint As Joint, R As Integer, myBrush As Brush)
    Dim myEllipse = New Ellipse
    With myEllipse
        .Width = R
        .Height = R
        .Fill = myBrush
    End With

    point = myKinect.CoordinateMapper.MapCameraPointToDepthSpace(myJoint.Position) (1)
    If point.X < 0 OrElse point.Y < 0 Then
        Return
    End If
    Canvas.SetLeft(myEllipse, point.X - (R / 2))   (2)
    Canvas.SetTop(myEllipse, point.Y - (R / 2))
    If myJoint.JointType = JointType.HandRight Then
        Select Case Index   (3)
            Case 1
                myMap.ZoomLevel += 0.1
            Case 2
                myMap.ZoomLevel -= 0.1
            Case 3
                Index = 0
                Exit Sub
        End Select
    End If
    CanvasBody.Children.Add(myEllipse)
End Sub

透明な直径10ピクセルの円を作成します。直径はDrawEllipseを呼ぶ際に指定しています(リスト4)。

  1. CoordinateMapper.MapCameraPointToDepthSpaceメソッドで、関節の位置を、カメラ空間から距離空間へのポイントにマップし、メンバー変数pointで参照します。
  2. SetLeftとSetTopメソッドで透明な円を、指定したXとY軸に描きます。
  3. メンバー変数Indexの値で条件分岐を行います。Indexの値が1、つまり手の状態がパーなら地図を0.1ずつズームインし、Indexの値が2、つまり手の状態がグーなら地図を0.1ずつズームアウトします。

ウインドウが閉じられる場合の処理

リスト7:MainWindow.xaml.vbの一部(リスト6の続き)

Private Sub MainWindow_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    If myKinect Is Nothing = False Then
        myKinect.Close()
        myKinect = Nothing
    End If
End Sub
End Class

Kinectが動作している場合は、Kinectを閉じ、全ての関連付けから解放します。

実際に動作させてみた際の画面は、動画1のようになります。

Think IT会員限定特典
  • Kinect v2でBing Mapsを操作するプログラム

    『作りながら学ぶKinect v2プログラミング開発』 第5回のサンプルプログラムです。
薬師寺国安事務所

薬師寺国安事務所代表。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のWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

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