Kinect Joint - 未将对象引用设置为对象的实例

时间:2014-03-02 19:36:22

标签: c# object kinect instance-variables kinect-sdk

我设法创建了一个kinect应用程序,它读取某个骨架关节的X,Y,Z位置,然后对姿势进行分类(站立,坐着......)。应用程序也将分类结果输出到txt文件。

在我的主窗口中,我有骨架显示,用于将当前位置保存到训练数据集的按钮,用于对当前姿势进行分类的按钮以及文本框,应在何处显示分类结果。

应用程序运行没有错误。它还将当前位置保存到按钮点击的训练集上。但是,当我单击我的分类按钮时,应用程序冻结,在Visual Studio中我收到错误:

  

对象引用未设置为对象的实例。

这是一段代码,其中包含我收到错误的行(它位于foreach循环中 - 我在那里添加了注释行):

public partial class MainWindow : Window
{
    KinectSensor sensor = KinectSensor.KinectSensors[0];
    private double shoulderRightY;
    private double shoulderLeftY;
    private double headY;
    private double hipY;

    public MainWindow()
    {
        InitializeComponent();

        //After Initialization subscribe to the loaded event of the form 
        Loaded += MainWindow_Loaded;

        //After Initialization subscribe to the unloaded event of the form
        //We use this event to stop the sensor when the application is being closed.
        Unloaded += MainWindow_Unloaded;
    }

    void MainWindow_Unloaded(object sender, RoutedEventArgs e)
    {
        //stop the Sestor 
        sensor.Stop();
    }

    void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        //Create a Drawing Group that will be used for Drawing 
        this.drawingGroup = new DrawingGroup();

        //Create an image Source that will display our skeleton
        this.imageSource = new DrawingImage(this.drawingGroup);

        //Display the Image in our Image control
        Image.Source = imageSource;

        try
        {
            //Check if the Sensor is Connected
            if (sensor.Status == KinectStatus.Connected)
            {
                //Start the Sensor
                sensor.Start();
                //Tell Kinect Sensor to use the Default Mode(Human Skeleton Standing) || Seated(Human Skeleton Sitting Down)
                sensor.SkeletonStream.TrackingMode = SkeletonTrackingMode.Default;
                //Subscribe to te  Sensor's SkeletonFrameready event to track the joins and create the joins to display on our image control
                sensor.SkeletonFrameReady += sensor_SkeletonFrameReady;
                //nice message with Colors to alert you if your sensor is working or not
                Message.Text = "Kinect Ready";
                Message.Background = new SolidColorBrush(Colors.Green);
                Message.Foreground = new SolidColorBrush(Colors.White);

                // Turn on the skeleton stream to receive skeleton frames
                this.sensor.SkeletonStream.Enable();
            }
            else if (sensor.Status == KinectStatus.Disconnected)
            {
                //nice message with Colors to alert you if your sensor is working or not
                Message.Text = "Kinect Sensor is not Connected";
                Message.Background = new SolidColorBrush(Colors.Orange);
                Message.Foreground = new SolidColorBrush(Colors.Black);

            }
            else if (sensor.Status == KinectStatus.NotPowered)
            {//nice message with Colors to alert you if your sensor is working or not
                Message.Text = "Kinect Sensor is not Powered";
                Message.Background = new SolidColorBrush(Colors.Red);
                Message.Foreground = new SolidColorBrush(Colors.Black);
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    /// <summary>
    //When the Skeleton is Ready it must draw the Skeleton
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
    {
        //declare an array of Skeletons
        Skeleton[] skeletons = new Skeleton[1];

        //Opens a SkeletonFrame object, which contains one frame of skeleton data.
        using (SkeletonFrame skeletonframe = e.OpenSkeletonFrame())
        {
            //Check if the Frame is Indeed open 
            if (skeletonframe != null)
            {

                skeletons = new Skeleton[skeletonframe.SkeletonArrayLength];

                // Copies skeleton data to an array of Skeletons, where each Skeleton contains a collection of the joints.
                skeletonframe.CopySkeletonDataTo(skeletons);

                //draw the Skeleton based on the Default Mode(Standing), "Seated"
                if (sensor.SkeletonStream.TrackingMode == SkeletonTrackingMode.Default)
                {
                    //Draw standing Skeleton
                    DrawStandingSkeletons(skeletons);
                }
                else if (sensor.SkeletonStream.TrackingMode == SkeletonTrackingMode.Seated)
                {
                    //Draw a Seated Skeleton with 10 joints
                    DrawSeatedSkeletons(skeletons);
                }
            }
        }

        foreach (Skeleton skeleton in skeletons)
        {
            //HERE IS THE ERROR
            Joint rightShoulder = skeleton.Joints[JointType.ShoulderRight];
            Joint leftShoulder = skeleton.Joints[JointType.ShoulderLeft];
            Joint head = skeleton.Joints[JointType.Head];
            Joint hip = skeleton.Joints[JointType.HipCenter];

            shoulderRightY += rightShoulder.Position.Y;
            shoulderLeftY += leftShoulder.Position.Y;
            headY += head.Position.Y;
            hipY += hip.Position.Y;
        }
    }

有趣的是,它将这些值正确地保存到数据集中(没有错误)(它也使用了foreach循环)。这是数据集按钮:

   // button click method
    private void stoji_Click(object sender, RoutedEventArgs e)
    {
        File.AppendAllText(@"E:\KINECT\inputs.txt", shoulderRightY + " " + shoulderLeftY + " " + headY + " " + hipY + Environment.NewLine);
        File.AppendAllText(@"E:\KINECT\outputs.txt", "1" + Environment.NewLine);
    }

这是我的分类按钮。 Program类位于单独的.cs文件中,并且有一个SVM正在执行多类分类。它正确地对案例进行了分类,因为它在我的txt文件中写入了正确的结果。

 private void classify_Click(object sender, RoutedEventArgs e)
 {
        if (File.Exists(@"E:\KINECT\test.txt"))
        {
            File.Delete(@"E:\KINECT\test.txt");
        }
        File.AppendAllText(@"E:\KINECT\test.txt", shoulderRightY + " " + shoulderLeftY + " " + headY + " " + hipY + Environment.NewLine);

        double detect = Program.siet();
        vysledok.Text = detect.ToString();
}

编辑:

这是我的“Program.cs”所做的。作为O.R. Mapper说:“我怀疑在Program.siet()的某个地方调用了sensor_SkeletonFrameReady”。我在这里看不到它。

 using System ;
 using System . Collections.Generic ;
 using System . Linq ;
 using System . Text ;
 using Encog . Neural.Networks ;
 using Encog . Neural.Networks.Layers ;
 using Encog . Engine.Network.Activation ;
 using Encog .ML.Data;
 using Encog . Neural.Networks.Training.Propagation.Resilient ;
 using Encog .ML.Train;
 using Encog .ML.Data.Basic ;
 using System.IO;
 using System.Collections;
 using Encog.ML.SVM;
 using Encog.ML.SVM.Training;


 public class Program
 {

 public static double siet()
 {

 string cestain = @"E:\KINECT\inputs.txt";
 double[][] innput = Load.FromFile(cestain);

 string cestaout = @"E:\KINECT\outputs.txt";
 double[][] ooutput = Load.FromFile(cestaout);

 double[] skuska1 = File.ReadAllText(@"E:\KINECT\test.txt").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(double.Parse).ToArray();


    // c r e a t e a neural network , wi thout us ing a f a c t o r y

    var svm = new SupportVectorMachine(2, false);

        // c r e a t e t r a i n i n g data
     IMLDataSet trainingSet = new BasicMLDataSet(innput, ooutput);

     // t r a i n the neural network
     /*IMLTrain train = new ResilientPropagation(network, trainingSet);*/

     IMLTrain train = new SVMSearchTrain(svm, trainingSet);
     int epoch = 1;

    do
    {
        train.Iteration();
        Console.WriteLine(@"Epoch #" + epoch + @" Error:" + train.Error);
        epoch++;
    } while (train.Error > 0.01);
    // t e s t the neural network

    Console.WriteLine(@"SVM Results:");

    IMLData output = svm.Compute(new BasicMLData(skuska1));
        Console.WriteLine(skuska1
                          + @", actual=" + output[0]);

        File.AppendAllText(@"E:\KINECT\testout.txt", output[0].ToString());


        return output[0];
 }
 }

这是Load.cs:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.IO;
 using System.Collections;

 public class Load
 {
public Load()
{
}

  public static double[][] FromFile(string path)
 {
    var rows = new List<double[]>();
    foreach (var line in File.ReadAllLines(path))
    {
        rows.Add(line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(double.Parse).ToArray());
    }
    return rows.ToArray();
}
}

1 个答案:

答案 0 :(得分:0)

这是解决方案:

  foreach (Skeleton skeleton in skeletons)
            {
                if (skeleton != null)
                {
                    hip = skeleton.Joints[JointType.HipCenter];
                    rightShoulder = skeleton.Joints[JointType.ShoulderRight];
                    leftShoulder = skeleton.Joints[JointType.ShoulderLeft];
                    head = skeleton.Joints[JointType.Head];


                    shoulderRightY += rightShoulder.Position.Y;
                    shoulderLeftY += leftShoulder.Position.Y;
                    headY += head.Position.Y;
                    hipY += hip.Position.Y;
                }


        }

任何人都可以验证吗?