我设法创建了一个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();
}
}
答案 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;
}
}
任何人都可以验证吗?