PR

Kinectで手の動きとカーソルを連動して操作するサンプル

2012年7月30日(月)
薬師寺 国安

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト3のコードを記述します。

ロジックコードを記述する

リスト3 (MainWindow.xaml.vb)

Option Strict On
Imports Coding4Fun.Kinect.Wpf
Imports System.Windows.Media.Imaging

画像の移動を可能にするMultiTouch.Behaviors.WPF4名前空間をインポートしておきます。

Imports MultiTouch.Behaviors.WPF4

手の動きとカーソルの動きを連動して、カーソルの現在位置で、ホールドやホールドの解除を提供する、CursorClass.KinectCursor名前空間をインポートしておきます。

Imports CursorClass.KinectCursor

Imports Microsoft.Kinect

Class MainWindow

マルチタッチの機能を提供するクラスである、MultiTouchBehaviorクラス用メンバ変数behaviorを宣言します。

  Dim behavior As MultiTouchBehavior

Imageクラスのメンバ変数myImageを宣言します。

  Dim myImage As Image
  
  Dim no As Integer = 10
  Dim newSensor As KinectSensor

定数メンバ変数を宣言し、それぞれの値で初期化しておきます。マウスカーソルがスムーズに動作する以下の値を設定してください。

  Const SkeletonMaxX As Single = 0.6F
  Const SkeletonMaxY As Single =0.4F
  Const ClickThreshold As Single = 0.33F

XML要素を表すXElementクラス用メンバ変数xmldocを宣言します。

 Dim xmldoc As XElement

Imageクラス型のメンバ変数_imageを宣言しておきます。

  Dim _image As Image

ウィンドウが読み込まれた時の処理

XElement.LoadメソッドでXML文書ファイル(photo_etc.xml)を読み込みます。
Descendants メソッドで、子孫要素であるすべての 要素のコレクションに対して、各要素を変数 result に格納しながら、以下の処理を行います。

新しいImageのインスタンスmyImageオブジェクトを作成します。

新しいMultiTouchBehaviorのインスタンスbehaviorオブジェクトを作成します。

ImageオブジェクトのWidthとHeightのプロパティを設定し、SourceプロパティにImageフォルダを付加した、要素の値を指定します。

ImageShowAreaという名前を持つCanvasにAddメソッドで画像を追加します。
10枚の画像が同じ位置に重なって表示されます。

画像の上でマウスの左ボタンが押された時(画像の上にマウスカーソルが乗り、左手が上から下に振り下ろされた時)のイベントハンドラを追加します。
増加する変数noの値を画像のZIndexPropertyの値に指定し、選択された画像が前面に表示されるようにします。
Attachメソッドで画像にアタッチします。

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メソッドでRGBカメラの機能を有効にします。
ColorImageFormat.RgbResolution640x480Fps30列挙体で「RGBフォーマットで、解像度は640×480、フレームレートは毎秒30フレーム」と設定します。

RGBカメラ、距離カメラ、スケルトンのフレーム更新を同時に行うイベントAllFramesReadyにイベントハンドラを指定します。
RGBカメラを有効にしてカメラの画像を表示するSensorColorFrameReady、スケルトンのフレーム更新を行い手の動きでマウスカーソルを操作する、SensorSkeletonReadyプロシージャを実行します。

Kinectセンサーを開始します。例外が発生した場合はエラーを表示して処理を抜けます。

  Private Sub MainWindow_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    xmldoc = XElement.Load("photo_etc.xml")
    For Each result In From c In xmldoc.Descendants("画像名") Select c
      myImage = New Image
      behavior = New MultiTouchBehavior
      With myImage
        .Width = 320
        .Height = 240
        .Source = New BitmapImage(New Uri("Image/" & result.Value, UriKind.Relative))
      End With
 
      ImageShowArea.Children.Add(myImage)
 
      AddHandler myImage.MouseLeftButtonDown, Sub(mouseSender As Object, mouseArgs As MouseButtonEventArgs)
                                _image = DirectCast(mouseArgs.Source, Image)
                                no = no + 1
                                _image.SetValue(Canvas.ZIndexProperty, no)
                         End Sub
      behavior.Attach(myImage)
    Next
 
    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)
      End With
 
    AddHandler newSensor.AllFramesReady, Sub(frameSender As Object, frameArgs As AllFramesReadyEventArgs)
              SensorSkeletonReady(frameArgs)
              SensorColorFrameReady(frameArgs)
            End Sub
              Try
                newSensor.Start()
              Catch ex As Exception
                MessageBox.Show(ex.Message)
                  Exit Sub
                End Try
            End Sub
  End Sub
Think IT会員限定特典
  • Kinectで手の動きに合わせてカーソルを動かすサンプル

薬師寺国安事務所

薬師寺国安事務所代表。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会員サービスの概要とメリットをチェック

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