MS Kinect SDKはこれまでのOpenNI相当で、ジェスチャーを検出するNITE相当の機能はありませんでした。
それを解消するライブラリが先日リリースされたようなので少し触ってみました。実はWPFをまともに触るのは初めてなのですが、先日のWindowsPhoneのセミナーで少し触ったので、なんとかなりましたw
- 紹介
- バイナリおよびソース
参考
調べてる過程で、Kinect.Toolkitのサンプルアプリ集のサイトを見つけました(フランスのMS?)。ただしToolkitのバージョンが古いようで、Codeprexで配布されているライブラリとは若干インタフェースが違うようです
Kinect pour Windows SDK - Démos
その中からいくつかやってみました
これは何?
Kinect.ToolkitはC#(WPF+XNA)のライブラリで以下の機能があるようです
- SwipeGestureDetectorによるスワイプの検出(手の左右移動)
- SwipeToLeft(左に移動)
- SwipeToRight(右に移動)
- TemplateGestureDetectorによるテンプレートジェスチャーの検出(主に円)
- PostureDetectorによるポーズの検出
- None(ポーズなし)
- HandsJoined(両手を合わせた?)
- LeftHandOverHead(左手が頭の上)
- RightHandOverHead(右手が頭の上)
- LeftHello(左手でこんにちは)
- RightHello(右手でこんにちは)
- SkeletonDisplayManagerやGestureDetectorsによる描画のサポート
- ColorStreamManagerやDepthStreamManagerによる描画のサポート
- スケルトンの記録と再生
- BindableNUICameraによるチルトのデータバインディングサポート
サンプルソース
サンプルなど参考に、こんなのを作ってみました。ただし、ポーズの検出はできますが、ジェスチャーの検出が難しくて1回しかできてません
- ツールキットを使ったカメラとスケルトンの描画
- ジェスチャーの検出
- ポーズの検出
- https://github.com/kaorun55/kinect_sdk_sandbox/tree/master/kinect_sdk_samples_cs/kinect_toolkit
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Microsoft.Research.Kinect.Nui; using Kinect.Toolkit; using System.Diagnostics; namespace kinect_toolkit { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { Runtime kinectRuntime; readonly ColorStreamManager colorStreamManager = new ColorStreamManager(); // カメラ画像の描画サポート readonly GestureDetector rightHandGestureRecognizer = new SwipeGestureDetector(); // ジェスチャーの検出器 readonly BarycenterHelper barycenterHelper = new BarycenterHelper(30); // 重心 readonly PostureDetector postureRecognizer = new PostureDetector(); // ポーズの検出器 SkeletonDisplayManager skeletonDisplayManager; // ジェスチャーの描画サポート public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { // Init Kinect try { kinectRuntime = new Runtime(); kinectRuntime.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseColor); kinectRuntime.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color); kinectRuntime.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex); kinectRuntime.SkeletonFrameReady += kinectRuntime_SkeletonFrameReady; kinectRuntime.VideoFrameReady += kinectRuntime_ColorFrameReady; kinectRuntime.SkeletonEngine.TransformSmooth = true; var parameters = new TransformSmoothParameters { Smoothing = 0.7f, Correction = 0.3f, Prediction = 0.4f, JitterRadius = 1.0f, MaxDeviationRadius = 0.5f }; kinectRuntime.SkeletonEngine.SmoothParameters = parameters; skeletonDisplayManager = new SkeletonDisplayManager(kinectRuntime.SkeletonEngine, skeletonCanvas); // Events rightHandGestureRecognizer.OnGestureDetected += rightHandGestureRecognizer_OnGestureDetected; } catch(Exception ex ) { MessageBox.Show(ex.Message); Close(); kinectRuntime = null; } } void rightHandGestureRecognizer_OnGestureDetected(SupportedGesture gesture) { switch (gesture) { case SupportedGesture.SwipeToLeft: Gesture.Content = "GestureDetected:SwipeToLeft"; break; case SupportedGesture.SwipeToRight: Gesture.Content = "GestureDetected:SwipeToRight"; break; } } void kinectRuntime_ColorFrameReady(object sender, ImageFrameReadyEventArgs e) { // カメラ画像の描画 ColorImage.Source = colorStreamManager.Update(e); } void kinectRuntime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e) { SkeletonFrame skeletonFrame = e.SkeletonFrame; foreach (SkeletonData data in skeletonFrame.Skeletons) { if (data.TrackingState != SkeletonTrackingState.Tracked) continue; barycenterHelper.Add(data.Position.ToVector3(),data.TrackingID); if (!barycenterHelper.IsStable(data.TrackingID)) continue; foreach (Joint joint in data.Joints) { if (joint.Position.W < 0.8f || joint.TrackingState != JointTrackingState.Tracked) continue; if (joint.ID == JointID.HandRight) { rightHandGestureRecognizer.Add(joint.Position, kinectRuntime.SkeletonEngine); Trace.WriteLine(Gesture.Content = "HandRight.Add"); } } // ポーズの検出 postureRecognizer.TrackPostures(data); } // スケルトンの描画 skeletonDisplayManager.Draw(e.SkeletonFrame); labelPose.Content = "Pose: " + postureRecognizer.CurrentPosture.ToString(); } } }