Exporting skeleton coordinates into .csv file

Category: kinect for windows v1 sdk

Question

JohnnySoung on Sun, 29 Jun 2014 02:01:42


Hi guys. 

I'm new to Kinect programming and I've been trying to programming Kinect in C# for about 4 weeks.

What I want to do with Kinect is to:

1. show the coordinates of each joints(or whichever joints I want to show) on the skeleton while the person is moving. 

2. Saving the skeleton coordinates of all 20 joints into .csv file so I can using these coordinates to represent and recover the movement of person in order to do further process. 

I have done my goal 1. I can show the coordinates of joints on the skeleton. And as to goal 2, I can get a file which record the skeleton data. What I want is the the coordinates of 20 joints for a certain time period. I want all these coordinates variation listed in my .csv file. But the problem is the file I got has only the coordinates of 20 joints for the first frame. Or at least I think that is what happened. Anyway, I only got coordinates for one frame. I have done lots of search online and still I have no solution. I found an post that someone is working on the similar work with me. Here is the link: 

http://social.msdn.microsoft.com/Forums/en-US/c6b1238e-d59d-45fa-a2cb-3d04c469c2fa/saving-skeletal-coordinates-to-file-based-on-kinect-explorer?forum=kinectsdknuiapi

In this post, someone suggested that should incrementing TotalFrames in order to got coordinates of other frames except the first frame. But What the HECK is this TotalFrames?!! I couldn't find it anywhere. And the guy who wrote this in his code, he didn't even bring this up in his code. What he did is just one statement in his method: TotalFrames++  ... I couldn't possibly understand. If someone can help me out of this, please help me. It has been several days I tried to figure this out. 

I wrote a method called ExportCSVFile() and I posted it at the bottom. I called it in my AllFramesReady event handler. Here is ExportCSVFile() method: 

private void ExportCSVFile(Skeleton skeleton)
        {
            StreamWriter headerWriter = new StreamWriter(@"C:\Users\JohnnySong\Desktop\SkeletonData.csv");
            headerWriter.WriteLine("SkelId" + "," + "Joint Type" + "," + "Confidence" + "," + "X" + "," + "Y");
            headerWriter.Close();

            StreamWriter coordinatesWriter = new StreamWriter(@"C:\Users\JohnnySong\Desktop\SkeletonData.csv", true);

            foreach (Joint joints in skeleton.Joints)
            {
                coordinatesWriter.WriteLine(skeleton.TrackingId + "," + joints.JointType + "," + joints.TrackingState +
                                            "," + joints.Position.X + "," + joints.Position.Y);
            }
            coordinatesWriter.Close();
        }

And here is my code: 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
using Coding4Fun.Kinect.Wpf;
using System.IO;

namespace Skeleton_Joints_Coordinates
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        bool closing = false;
        const int skeletonCount = 6;
        Skeleton[] allSkeletons = new Skeleton[skeletonCount];

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            kinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(kinectSensorChooser1_KinectSensorChanged);
        }

        void kinectSensorChooser1_KinectSensorChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            KinectSensor old = (KinectSensor)e.OldValue;
            StopKinect(old);

            KinectSensor sensor = (KinectSensor)e.NewValue;

            if (sensor == null)
            {
                return;
            }

            var parameters = new TransformSmoothParameters
            {
                Smoothing = 0.3f,
                Correction = 0.0f,
                Prediction = 0.0f,
                JitterRadius = 1.0f,
                MaxDeviationRadius = 0.5f
            };
            //sensor.SkeletonStream.Enable(parameters);

            sensor.SkeletonStream.Enable();
            sensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(sensor_AllFramesReady);
            sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
            sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);

            try
            {
                sensor.Start();
            }
            catch (System.IO.IOException)
            {
                kinectSensorChooser1.AppConflictOccurred();
            }
        }

        void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            if (closing)
            {
                return;
            }

            //Get a skeleton
            Skeleton first = GetFirstSkeleton(e);

            if (first == null)
            {
                return;
            }

            // Set scaled position; TODO: show coordinates

            //ScalePosition(headLabel, first.Joints[JointType.Head]);
            ScalePosition(leftHandLabel, first.Joints[JointType.HandLeft]);
            //ScalePosition(rightHandLabel, first.Joints[JointType.HandRight]);
            //ScalePosition(spineEllipse, first.Joints[JointType.Spine]);
            //ScalePosition(leftFootEllipse, first.Joints[JointType.FootLeft]);
            //ScalePosition(rightFootEllipse, first.Joints[JointType.FootRight]);


            // Obtain joints; print its coordinate out if it's tracked
            // Head
            //if (first.Joints[JointType.Head].TrackingState == JointTrackingState.Tracked)
            //{
            //    headLabel.Content = "Head coordinate:" + first.Joints[JointType.Head].Position.X + "\n" + 
            //        first.Joints[JointType.Head].Position.Y;
            //}

            // Left hand
            if (first.Joints[JointType.HandLeft].TrackingState == JointTrackingState.Tracked)
            {
                leftHandLabel.Content = "LeftHand coordinate:" + first.Joints[JointType.HandLeft].Position.X + "\n" +
                    first.Joints[JointType.HandLeft].Position.Y;
            }

            // Right hand
            //if (first.Joints[JointType.HandRight].TrackingState == JointTrackingState.Tracked)
            //{
            //    rightHandLabel.Content = "RightHand coordinate:" + first.Joints[JointType.HandRight].Position.X + "\n" +
            //        first.Joints[JointType.HandRight].Position.Y;
            //}

            // Generate .csv file 
            ExportCSVFile(first);

            GetCameraPoint(first, e);
        }

        void GetCameraPoint(Skeleton first, AllFramesReadyEventArgs e)
        {

            using (DepthImageFrame depth = e.OpenDepthImageFrame())
            {
                if (depth == null ||
                    kinectSensorChooser1.Kinect == null)
                {
                    return;
                }


                //Map a joint location to a point on the depth map
                // Head
                DepthImagePoint headDepthPoint =
                    depth.MapFromSkeletonPoint(first.Joints[JointType.Head].Position);
                // Left hand
                DepthImagePoint leftHandDepthPoint =
                    depth.MapFromSkeletonPoint(first.Joints[JointType.HandLeft].Position);
                // Right hand
                DepthImagePoint rightHandDepthPoint =
                    depth.MapFromSkeletonPoint(first.Joints[JointType.HandRight].Position);
                //// Spine
                //DepthImagePoint spineDepthPoint =
                //    depth.MapFromSkeletonPoint(first.Joints[JointType.Spine].Position);
                //// Left foot
                //DepthImagePoint leftFootDepthPoint =
                //    depth.MapFromSkeletonPoint(first.Joints[JointType.FootLeft].Position);
                //// Right foot
                //DepthImagePoint rightFootDepthPoint =
                //    depth.MapFromSkeletonPoint(first.Joints[JointType.FootRight].Position);


                //Map a depth point to a point on the color image
                // Head
                ColorImagePoint headColorPoint =
                    depth.MapToColorImagePoint(headDepthPoint.X, headDepthPoint.Y,
                    ColorImageFormat.RgbResolution640x480Fps30);
                // Left hand
                ColorImagePoint leftHandColorPoint =
                    depth.MapToColorImagePoint(leftHandDepthPoint.X, leftHandDepthPoint.Y,
                    ColorImageFormat.RgbResolution640x480Fps30);
                // Right hand
                ColorImagePoint rightHandColorPoint =
                    depth.MapToColorImagePoint(rightHandDepthPoint.X, rightHandDepthPoint.Y,
                    ColorImageFormat.RgbResolution640x480Fps30);
                //// Spine
                //ColorImagePoint spineColorPoint =
                //    depth.MapToColorImagePoint(spineDepthPoint.X, spineDepthPoint.Y,
                //    ColorImageFormat.RgbResolution640x480Fps30);
                //// Left Foot
                //ColorImagePoint leftFootColorPoint =
                //    depth.MapToColorImagePoint(leftFootDepthPoint.X, leftFootDepthPoint.Y,
                //    ColorImageFormat.RgbResolution640x480Fps30);
                //// Right Foot
                //ColorImagePoint rightFootColorPoint =
                //    depth.MapToColorImagePoint(rightFootDepthPoint.X, rightFootDepthPoint.Y,
                //    ColorImageFormat.RgbResolution640x480Fps30);


                //Set location
                //CameraPosition(headLabel, headColorPoint);
                CameraPosition(leftHandLabel, leftHandColorPoint);
                //CameraPosition(rightHandLabel, rightHandColorPoint);
                //CameraPosition(spineEllipse, spineColorPoint);
                //CameraPosition(leftFootEllipse, leftFootColorPoint);
                //CameraPosition(rightFootEllipse, rightFootColorPoint);

                // If using this to get coordinates, you'll get the colorData-mapped skeleton coordinates
                //{
                //    leftHandLabel.Content = leftHandColorPoint.X + "\n" + leftHandColorPoint.Y;
                //}

            }
        }


        Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e)
        {
            using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame())
            {
                if (skeletonFrameData == null)
                {
                    return null;
                }
                

                skeletonFrameData.CopySkeletonDataTo(allSkeletons);

                //get the first tracked skeleton
                Skeleton first = (from s in allSkeletons
                                  where s.TrackingState == SkeletonTrackingState.Tracked
                                  select s).FirstOrDefault();
                
                return first;
            }
        }


        private void StopKinect(KinectSensor sensor)
        {
            if (sensor != null)
            {
                if (sensor.IsRunning)
                {
                    //stop sensor 
                    sensor.Stop();

                    //stop audio if not null
                    if (sensor.AudioSource != null)
                    {
                        sensor.AudioSource.Stop();
                    }


                }
            }
        }


        private void CameraPosition(FrameworkElement element, ColorImagePoint point)
        {
            //Divide by 2 for width and height so point is right in the middle 
            // instead of in top/left corner
            Canvas.SetLeft(element, point.X - element.Width / 2);
            Canvas.SetTop(element, point.Y - element.Height / 2);

        }


        private void ScalePosition(FrameworkElement element, Joint joint)
        {
            //convert the value to X/Y
            Joint scaledJoint = joint.ScaleTo(1280, 720);

            //convert & scale (.3 = means 1/3 of joint distance)
            //Joint scaledJoint = joint.ScaleTo(1280, 720, .3f, .3f);

            Canvas.SetLeft(element, scaledJoint.Position.X);
            Canvas.SetTop(element, scaledJoint.Position.Y);

        }


        private void ExportCSVFile(Skeleton skeleton)
        {
            StreamWriter headerWriter = new StreamWriter(@"C:\Users\JohnnySong\Desktop\SkeletonData.csv");
            headerWriter.WriteLine("SkelId" + "," + "Joint Type" + "," + "Confidence" + "," + "X" + "," + "Y");
            headerWriter.Close();

            StreamWriter coordinatesWriter = new StreamWriter(@"C:\Users\JohnnySong\Desktop\SkeletonData.csv", true);

            foreach (Joint joints in skeleton.Joints)
            {
                coordinatesWriter.WriteLine(skeleton.TrackingId + "," + joints.JointType + "," + joints.TrackingState +
                                            "," + joints.Position.X + "," + joints.Position.Y);
            }
            coordinatesWriter.Close();
        }
        
        
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            closing = true;
            StopKinect(kinectSensorChooser1.Kinect);
        }
    }
}

Again, if you could help me, please help me out of this. I'm grateful for that! Thanks! 

Replies

TechSultan on Tue, 01 Jul 2014 15:19:06


Check out Vangos' work below

http://pterneas.com/2014/05/06/understanding-kinect-coordinate-mapping/

He shows, and provides a GitHub link, to a program he made to show joints on the screen. From there it's just a short step to printing to file the joint positions as the program loops through each joint.

Hope it helps!

Mikey6787 on Sat, 20 Sep 2014 19:34:29


hi mr . JohnnySoung i want to do similar thing , I'm student of biomechanics and i want to get kinect to do as a motion capture camera i have purchase a kinect version 2 but i could not export coordination data to a csv file , did you found any solution for that mohamadreza.kharazi@live.com

Mark2496 on Wed, 18 Apr 2018 08:49:22


have you found a solution?