SDK v1.5 と VS2012 を使用して、Kinect for Windows でスケルトン トラッキングを適切に機能させるのに深刻な問題が発生しています。https://github.com/EvilClosetMonkey/Fizbin.Kinect.Gesturesのソース コードに基づいて構築していますが、画面に複数の人がいると追跡が完全に狂ってしまいます。次に、ここでコードを確認しました ( http://social.msdn.microsoft.com/Forums/en-US/kinectsdknuiapi/thread/459012d7-d51e-460d-aa6a-a1b80c27626c/ )。 「AppChoosesSkeletons」機能の統合を試みました (以下のコード):
using System.Windows;
using System.Windows.Data;
using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit;
using Microsoft.Samples.Kinect.WpfViewers;
using System.Diagnostics;
using System.ComponentModel;
using System.Linq;
using System;
namespace Fizbin.Kinect.Gestures.Demo
{
public partial class MainWindow : Window, INotifyPropertyChanged
{
private readonly KinectSensorChooser sensorChooser = new KinectSensorChooser();
private Skeleton[] skeletons = new Skeleton[0];
// skeleton gesture recognizer
private GestureController gestureController;
public MainWindow()
{
DataContext = this;
InitializeComponent();
// initialize the Kinect sensor manager
KinectSensorManager = new KinectSensorManager();
KinectSensorManager.KinectSensorChanged += this.KinectSensorChanged;
// locate an available sensor
sensorChooser.Start();
// bind chooser's sensor value to the local sensor manager
var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.KinectSensorManager, KinectSensorManager.KinectSensorProperty, kinectSensorBinding);
}
#region Kinect Discovery & Setup
private void KinectSensorChanged(object sender, KinectSensorManagerEventArgs<KinectSensor> args)
{
if (null != args.OldValue)
UninitializeKinectServices(args.OldValue);
if (null != args.NewValue)
InitializeKinectServices(KinectSensorManager, args.NewValue);
}
/// <summary>
/// Kinect enabled apps should customize which Kinect services it initializes here.
/// </summary>
/// <param name="kinectSensorManager"></param>
/// <param name="sensor"></param>
private void InitializeKinectServices(KinectSensorManager kinectSensorManager, KinectSensor sensor)
{
// Application should enable all streams first.
// configure the color stream
kinectSensorManager.ColorFormat = ColorImageFormat.RgbResolution640x480Fps30;
kinectSensorManager.ColorStreamEnabled = true;
// configure the depth stream
kinectSensorManager.DepthStreamEnabled = true;
kinectSensorManager.TransformSmoothParameters =
new TransformSmoothParameters
{
Smoothing = 0.5f,
Correction = 0.5f,
Prediction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius = 0.04f
};
// configure the skeleton stream
sensor.SkeletonFrameReady += FramesReady;
kinectSensorManager.SkeletonStreamEnabled = true;
sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Seated;
// initialize the gesture recognizer
gestureController = new GestureController();
gestureController.GestureRecognized += OnGestureRecognized;
kinectSensorManager.KinectSensorEnabled = true;
if (!kinectSensorManager.KinectSensorAppConflict)
{
// addition configuration, as needed
}
}
/// <summary>
/// Kinect enabled apps should uninitialize all Kinect services that were initialized in InitializeKinectServices() here.
/// </summary>
/// <param name="sensor"></param>
private void UninitializeKinectServices(KinectSensor sensor)
{
}
#endregion Kinect Discovery & Setup
#region Properties
public static readonly DependencyProperty KinectSensorManagerProperty =
DependencyProperty.Register(
"KinectSensorManager",
typeof(KinectSensorManager),
typeof(MainWindow),
new PropertyMetadata(null));
public KinectSensorManager KinectSensorManager
{
get { return (KinectSensorManager)GetValue(KinectSensorManagerProperty); }
set { SetValue(KinectSensorManagerProperty, value); }
}
/// <summary>
/// Gets or sets the last recognized gesture.
/// </summary>
private string _gesture;
public String Gesture
{
get { return _gesture; }
private set
{
if (_gesture == value)
return;
_gesture = value;
Debug.WriteLine("Gesture = " + _gesture);
if (this.PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Gesture"));
}
}
#endregion Properties
#region Events
/// <summary>
/// Event implementing INotifyPropertyChanged interface.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion Events
#region Event Handlers
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e">Gesture event arguments.</param>
private void OnGestureRecognized(object sender, GestureEventArgs e)
{
Debug.WriteLine(e.GestureType);
switch (e.GestureType)
{
case GestureType.Menu:
Gesture = "Menu";
break;
case GestureType.WaveRight:
Gesture = "Wave Right";
break;
case GestureType.WaveLeft:
Gesture = "Wave Left";
break;
case GestureType.JoinedHands:
Gesture = "Joined Hands";
break;
case GestureType.SwipeLeft:
Gesture = "Swipe Left";
break;
case GestureType.SwipeRight:
Gesture = "Swipe Right";
break;
case GestureType.ZoomIn:
Gesture = "Zoom In";
break;
case GestureType.ZoomOut:
Gesture = "Zoom Out";
break;
default:
break;
}
}
void FramesReady(object sender, AllFramesReadyEventArgs e, KinectSensor sensor)
{
Skeleton skeleton = FindSkeleton(e);
if (skeleton != null)
{
gestureController.UpdateAllGestures(skeleton);
}
}
private int CurrentTrackingId = 0;
Skeleton FindSkeleton(AllFramesReadyEventArgs e)
{
Skeleton skeleton = null;
using (SkeletonFrame SFrame = e.OpenSkeletonFrame())
{
if (SFrame == null)
{
return null;
}
if (skeletons == null)
{
skeletons = new Skeleton[SFrame.SkeletonArrayLength];
}
SFrame.CopySkeletonDataTo(skeletons);
if (CurrentTrackingId != 0)
{
// We've been tracking someone; see if they're still here
skeleton =
(from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked &&
s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked &&
s.TrackingId == CurrentTrackingId
select s).FirstOrDefault();
if (skeleton == null)
{
CurrentTrackingId = 0;
sensor.SkeletonStream.AppChoosesSkeletons = false;
}
}
else
{
// Try to find someone new
skeleton =
(from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked &&
s.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked
select s).FirstOrDefault();
if (skeleton != null)
{
CurrentTrackingId = skeleton.TrackingId;
sensor.SkeletonStream.AppChoosesSkeletons = true;
sensor.SkeletonStream.ChooseSkeletons(CurrentTrackingId);
}
}
}
return skeleton;
}
#endregion Event Handlers
}
}
ただし、VS2012 から次のエラーが表示されます。
1) デリゲート「System.EventHandler」に一致する「FramesReady」のオーバーロードはありません
2)「センサー」が存在しない(おそらくインポートされていないためですが、私が試したところ、メソッド間でセンサーを渡すとエラーが発生します)
誰かがこれを手伝ってくれたり、これを解決するための正しい方向に私を向けたりすることができれば、それは素晴らしいことです! 繰り返しますが、主な目標は、Kinect が最初に見つけた人をロックし、複数の人が視線内を動き回ってもそのロックを維持することです。