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
  • 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 Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

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