使用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锁定在它找到的第一个人身上,并保持锁定,让多个人在视线中四处移动。
答案 0 :(得分:1)
如果您计划继续使用KinectSensorManager
,可以使用KinectSkeletonChooser
来帮助您挑选所需的骨架。此辅助函数也包含在KinectWpfViewers
项目中。您无需在后面的代码中添加任何其他代码即可使用它。
最简单的方法就是将其添加到您的XAML中。更新星期二图书馆除外的演示代码,它看起来像是:
<Window x:Class="Fizbin.Kinect.Gestures.Demo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:kv="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="320" Height="240">
<kv:KinectSkeletonChooser KinectSensorManager="{Binding KinectSensorManager}" SkeletonChooserMode="Sticky1Player" />
<kv:KinectDepthViewer x:Name="DepthViewer" KinectSensorManager="{Binding KinectSensorManager}" />
<Canvas>
<kv:KinectSkeletonViewer
KinectSensorManager="{Binding KinectSensorManager}"
Width="{Binding ElementName=DepthViewer, Path=ActualWidth}"
Height="{Binding ElementName=DepthViewer, Path=ActualHeight}"
ShowBones="True" ShowJoints="True" ShowCenter="True" ImageType="Depth" />
</Canvas>
</Grid>
<TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="-2,0,0,0"/>
<TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="2,0,0,0"/>
<TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="0,-2,0,0"/>
<TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Margin="0,2,0,0"/>
<TextBlock Text="{Binding Gesture}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" FontWeight="Bold" Foreground="White"/>
</Grid>
</Window>
请注意第8行的新KinectSkeletonChooser
标记。
其他可用选项可参见SkeletonChooserMode
枚举:
public enum SkeletonChooserMode
{
/// <summary>
/// Use system default tracking
/// </summary>
DefaultSystemTracking,
/// <summary>
/// Track the player nearest to the sensor
/// </summary>
Closest1Player,
/// <summary>
/// Track the two players nearest to the sensor
/// </summary>
Closest2Player,
/// <summary>
/// Track one player based on id
/// </summary>
Sticky1Player,
/// <summary>
/// Track two players based on id
/// </summary>
Sticky2Player,
/// <summary>
/// Track one player based on most activity
/// </summary>
MostActive1Player,
/// <summary>
/// Track two players based on most activity
/// </summary>
MostActive2Player
}