2014-03-02 51 views
2

我设法创建了一个kinect应用程序,该应用程序读取特定骨骼关节的X,Y,Z位置,并随后对姿势(站立,坐着......)进行分类... )。应用程序正在将分类结果输出到一个txt文件。Kinect Joint - 未将对象引用设置为对象的实例

在我的主窗口中,我有骨架显示,将当前位置保存到训练数据集的按钮,分类当前姿势的按钮和文本框,分类结果出现在哪里。

应用程序无误运行。它还将当前位置保存到按钮单击的训练集上。然而,当我点击我的分类按钮,应用程序冻结,并在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” 一样。正如O.R. 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(); 
} 
} 
+0

我有红色的话题,但它并没有真正的帮助。因为正如我所说的应用程序正在收集那些位置确定在该数据集按钮,这也使用foreach循环更新关节位置。当数据集按钮执行时,该行如何可能不为空,并且在执行分类时,该行为空。 Program类不用于关节,但仅适用于txt数据集文件。 – user2886091

+0

即使您声明如此,我在数据集按钮的click事件处理程序中看不到任何“foreach”循环。你可以在产生异常的行上设置一个断点后,用调试器运行你的程序,然后检查'skeleton'或'skeleton.Joints'是否为'null'? –

+0

可能是一个误解。我在SkeletonFrameReady方法中有一个foreach循环,其中位置被更新。对我来说有趣的是,仅在分类按钮单击时抛出异常。数据集按钮正常,它也适用于关节。 – user2886091

回答

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


     } 

任何人都可以验证?

相关问题