c# - Kinect 关节 - 对象引用未设置为对象的实例

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

<分区>

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

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

应用程序运行无误。它还将当前位置保存到单击按钮时的训练集。但是,当我单击我的分类按钮时,应用程序卡住并且在 Visual Studio 中出现错误:

Object reference not set to an instance of an object.

这是一段代码,其中包括出现错误的行(它在 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”所做的。作为手术室Mapper 说:“我怀疑 sensor_SkeletonFrameReady 是在 Program.siet() 的某个地方被调用的”。我在这里的任何地方都看不到它。

 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();
}
}

最佳答案

这是解决方案:

  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;
                }


        }

谁能验证一下?

关于c# - Kinect 关节 - 对象引用未设置为对象的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22132393/

相关文章:

通过处理控制 Kinect 电机

C# 更新密码 Renci.SshNet

.net - 将套接字排序为客户端对象

c# - Kinect 音频 PCM 值

c++ - Kinect SDK c++ 抓取和按下手势

java - Set 不适用于覆盖的 equals

c# - 使用 Linq 的 Where 子句 - 搜索对象列表

c# - 如何将 fixed 与 Array 或 T[] 类型的变量一起使用?

c# - 构造函数使用模拟对象,如何隔离测试方法?

java - 当没有构造函数的类的默认构造函数是 'automatically' 时,为什么编译器会提示父类(super class)没有构造函数?