none
How to write to disk/ save ColorStream and SkeltetonStream data Kinect SDK & XNA RRS feed

  • Question

  • I am new to the Kinect SDK and I am conducting Kinect SDK research. I have been working for about a week now to integrate the SDK with XNA. I finally got the RGB camera data to show on the screen, and tracking a joint proven by the white ball that moves with it.

    My ultimate goal is to find a way to save this Camera & Skeletal data to disk in order to review this data at a later date. Right now I can save the x, y coordinates to a txt file every cycle, but i'd like to record the video and/or frames as they occur.

    Any suggestions would be very helpful.

    C# btw.

     Here is my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Audio;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;
    using Microsoft.Xna.Framework.Media;
    using Microsoft.Kinect;
    using System.IO;



    namespace Kinect_Stroke
    {
        /// <summary>
        /// This is the main type for your game
        /// </summary>
        public class Game1 : Microsoft.Xna.Framework.Game
        {
            

            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
            StreamWriter writer = new StreamWriter("myfile.txt");

            StreamWriter writer2 = new StreamWriter("myRgbData.txt");
                

                

            Texture2D kinectRGBVideo;
            Texture2D overlay;
            Texture2D hand;

            Vector2 handPosition = new Vector2();

            KinectSensor kinectSensor;

            SpriteFont font;

            

            string connectedStatus = "Not connected";

            public Game1()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";

                graphics.PreferredBackBufferWidth = 640;
                graphics.PreferredBackBufferHeight = 480;

            }

            void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
            {
                if (this.kinectSensor == e.Sensor)
                {
                    if (e.Status == KinectStatus.Disconnected ||
                        e.Status == KinectStatus.NotPowered)
                    {
                        this.kinectSensor = null;
                        this.DiscoverKinectSensor();
                    }
                }
            }

            private bool InitializeKinect()
            {
                kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
                kinectSensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(kinectSensor_ColorFrameReady);

                // Skeleton Stream
            kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters()
            {
                Smoothing = 0.5f,
                Correction = 0.5f,
                Prediction = 0.5f,
                JitterRadius = 0.05f,
                MaxDeviationRadius = 0.04f
            });
                kinectSensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(kinectSensor_SkeletonFrameReady);
                try
                {
                    kinectSensor.Start();
                }
                catch
                {
                    connectedStatus = "Unable to start the Kinect Sensor";
                    return false;
                }
                return true;
            }

            void kinectSensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
            {
                using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
                {
                    if (skeletonFrame != null)
                    {
                        //int skeletonSlot = 0;
                        Skeleton[] skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];

                        skeletonFrame.CopySkeletonDataTo(skeletonData);
                        Skeleton playerSkeleton = (from s in skeletonData where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault();
                        if (playerSkeleton != null)
                        {
                            Joint rightHand = playerSkeleton.Joints[JointType.HandRight];
                            handPosition = new Vector2((((0.5f * rightHand.Position.X) + 0.5f) * (640)), (((-0.5f * rightHand.Position.Y) + 0.5f) * (480)));
                           
                            
                             
                        }
                    }
                }
            }

            void kinectSensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
            {
                using (ColorImageFrame colorImageFrame = e.OpenColorImageFrame())
                {
                    if (colorImageFrame != null)
                    {

                        byte[] pixelsFromFrame = new byte[colorImageFrame.PixelDataLength];

                        colorImageFrame.CopyPixelDataTo(pixelsFromFrame);

                        Color[] color = new Color[colorImageFrame.Height * colorImageFrame.Width];
                        kinectRGBVideo = new Texture2D(graphics.GraphicsDevice, colorImageFrame.Width, colorImageFrame.Height);

                        // Go through each pixel and set the bytes correctly
                        // Remember, each pixel got a Red, Green and Blue
                        int index = 0;
                        for (int y = 0; y < colorImageFrame.Height; y++)
                        {
                            for (int x = 0; x < colorImageFrame.Width; x++, index += 4)
                            {
                                color[y * colorImageFrame.Width + x] = new Color(pixelsFromFrame[index + 2], pixelsFromFrame[index + 1], pixelsFromFrame[index + 0]);
                            }
                        }

                        // Set pixeldata from the ColorImageFrame to a Texture2D
                        kinectRGBVideo.SetData(color);
                    }
                }
            }

            private void DiscoverKinectSensor()
            {
                foreach (KinectSensor sensor in KinectSensor.KinectSensors)
                {
                    if (sensor.Status == KinectStatus.Connected)
                    {
                        // Found one, set our sensor to this
                        kinectSensor = sensor;
                        break;
                    }
                }

                if (this.kinectSensor == null)
                {
                    connectedStatus = "Found none Kinect Sensors connected to USB";
                    return;
                }

                // You can use the kinectSensor.Status to check for status
                // and give the user some kind of feedback
                switch (kinectSensor.Status)
                {
                    case KinectStatus.Connected:
                    {
                            connectedStatus = "Status: Connected";
                            break;
                    }
                    case KinectStatus.Disconnected:
                    {
                            connectedStatus = "Status: Disconnected";
                            break;
                    }
                    case KinectStatus.NotPowered:
                    {
                            connectedStatus = "Status: Connect the power";
                            break;
                    }
                    default:
                    {
                            connectedStatus = "Status: Error";
                            break;
                    }
                }

                // Init the found and connected device
                if (kinectSensor.Status == KinectStatus.Connected)
                {
                    InitializeKinect();
                }
            }

            protected override void Initialize()
            {
                KinectSensor.KinectSensors.StatusChanged += new EventHandler<StatusChangedEventArgs>(KinectSensors_StatusChanged);
                DiscoverKinectSensor();

                base.Initialize();
            }

            protected override void LoadContent()
            {
                spriteBatch = new SpriteBatch(GraphicsDevice);

                kinectRGBVideo = new Texture2D(GraphicsDevice, 1337, 1337);
                hand = Content.Load<Texture2D>("hand");
                overlay = Content.Load<Texture2D>("UTCNSFREU");
                font = Content.Load<SpriteFont>("SpriteFont1");
            }

            protected override void UnloadContent()
            {
                kinectSensor.Stop();
                kinectSensor.Dispose();
            }

            protected override void Update(GameTime gameTime)
            {
                
                

                writer.WriteLine(handPosition);
                //kinectRGBVideo.SaveAsJpeg(1, 640, 480);
                //writer.Close();
                

                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();

                base.Update(gameTime);
            }

            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.CornflowerBlue);

                spriteBatch.Begin();
                spriteBatch.Draw(kinectRGBVideo, new Rectangle(0, 0, 640, 480), Color.White);
                spriteBatch.Draw(hand, handPosition, Color.White);
                spriteBatch.Draw(overlay, new Rectangle(0, 0, 640, 480), Color.White);
                spriteBatch.DrawString(font, connectedStatus, new Vector2(20, 80), Color.White);
                spriteBatch.End();

                base.Draw(gameTime);
            }






            public void Record(SkeletonFrame frame)
            {
                if (writer == null)
                    throw new Exception("You must call Start before calling Record");

                TimeSpan timeSpan = DateTime.Now.Subtract(referenceTime);
                referenceTime = DateTime.Now;
                writer.Write((long)timeSpan.TotalMilliseconds);
                writer.Write(frame.FloorClipPlane);
                writer.Write((int)frame.Quality);
                writer.Write(frame.NormalToGravity);

                writer.Write(frame.Skeletons.Length);

                foreach (SkeletonData skeleton in frame.Skeletons)
                {
                    writer.Write((int)skeleton.TrackingState);
                    writer.Write(skeleton.Position);
                    writer.Write(skeleton.TrackingID);
                    writer.Write(skeleton.EnrollmentIndex);
                    writer.Write(skeleton.UserIndex);
                    writer.Write((int)skeleton.Quality);

                    writer.Write(skeleton.Joints.Count);
                    foreach (Joint joint in skeleton.Joints)
                    {
                        writer.Write((int)joint.ID);
                        writer.Write((int)joint.TrackingState);
                        writer.Write(joint.Position);
                    }
                }
            }



     


            

        }
    }

    Friday, June 8, 2012 2:24 AM

All replies

  • Have you looked at Kinect Stduio? It records the Color and Depth streams from the Kinect. The skeletal data will be generated by the runtime when the depth data is played back.

    Friday, June 8, 2012 7:18 PM
  • yup, what Carmine said... Kinect Studio is new in the 1.5 Toolkit release.
    Monday, June 11, 2012 12:03 AM