我在使用 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) 'FramesReady' 没有重载匹配委托 'System.EventHandler'
2)“传感器”不存在(很可能是因为它没有被导入,但根据我的尝试,跨方法传递传感器会导致更多错误)
如果有人可以帮助解决这个问题,或者甚至为我指出解决这个问题的正确方向,那就太好了!重申一下,主要目标是让 Kinect 锁定它找到的第一个人,并在多人在视线范围内移动时保持该锁定。