1

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 が最初に見つけた人をロックし、複数の人が視線内を動き回ってもそのロックを維持することです。

4

1 に答える 1

1

を引き続き使用するKinectSensorManager場合は、 を使用しKinectSkeletonChooserて必要なスケルトンを選択できます。このヘルパー関数もKinectWpfViewersプロジェクトに含まれています。これを使用するために、コード ビハインドに追加のコードを追加する必要はありません。

これを実現する最も簡単な方法は、XAML に追加することです。Except on Tuesdays' ライブラリに付属するデモ コードを更新すると、次のようになります。

<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
}
于 2012-12-03T22:29:31.230 に答える