我设法创建了一个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();
}
}
我有红色的话题,但它并没有真正的帮助。因为正如我所说的应用程序正在收集那些位置确定在该数据集按钮,这也使用foreach循环更新关节位置。当数据集按钮执行时,该行如何可能不为空,并且在执行分类时,该行为空。 Program类不用于关节,但仅适用于txt数据集文件。 – user2886091
即使您声明如此,我在数据集按钮的click事件处理程序中看不到任何“foreach”循环。你可以在产生异常的行上设置一个断点后,用调试器运行你的程序,然后检查'skeleton'或'skeleton.Joints'是否为'null'? –
可能是一个误解。我在SkeletonFrameReady方法中有一个foreach循环,其中位置被更新。对我来说有趣的是,仅在分类按钮单击时抛出异常。数据集按钮正常,它也适用于关节。 – user2886091