none
How to calculate the distance of the head from the floor RRS feed

  • Question

  • Hi guys, i should development an application in C# whit Kinect.

    I would to calculate the distance of the head from the floor. I was able l to calculate the distance of the head from Kinect sensor but do not know how to calculate the coordinates of the floor.

    Can you help me?

    Thanks all.

    Thursday, May 16, 2013 7:08 AM

All replies

  • There are many approaches, and each will have good and bad things. You will need to choose. Here are some examples (there are even more):

    1. The Kinect SDK can provide the location of the floor (vFloorClipPlane) in the NUI_SKELETON_FRAME. Using this, you can find the distance between the floor under the head and the head itself. Same approach can also give you the relative location of the Kinect and you can apply that offset to all your coordinates to have them relative to the floor under the Kinect.
    2. You can use the accelerometer to augment/improve the floor approximation in (1) above.
    3. You can approximate the distance of the head-> floor to be equal to the distance from the head->foot. Get the coordinates of each from the skeleton frame.
    4. Filter the depthmap by a given "player". For that player's isolated depthmap pixels, get the skeleton coordinate for the top of the head and the bottom of the foot from this depthmap. Subtract to get the distance.
    5. Use point clouds with PCL, Kinect Fusion, or your own code to find the very top of the head and the floor and calculate the distance between them

    --Dale

    Thursday, May 16, 2013 11:10 AM
  • Ok, i have prepare this code for to calculate the distance of the head from the foot.

    but this code not found correctly and i would like to calculate the distance from the floor. Can you help me to modify my code for get (vFloorClipPlane) in the NUI_SKELETON_FRAME??

    Excuse me but i'm a novel.

    this 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;
    
    namespace TrackingHand
    {
     
    
        public partial class MainWindow : Window
        {
               int x;
    int nullo = 0;
    int m_eins = 1;
    int nCount = 0;
    
            KinectSensor sensor;
            private float[] rightHandPosition;
            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_Loaded(object sender, RoutedEventArgs e)
            {
                this.sensor = KinectSensor.KinectSensors.Where(item => item.Status == KinectStatus.Connected).FirstOrDefault();
                if (!this.sensor.SkeletonStream.IsEnabled){
                    this.sensor.SkeletonStream.Enable();
                    this.sensor.SkeletonFrameReady += sensor_SkeletonFrameReady;
                }
                this.sensor.Start();
              
            }
    
            
            void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
            {
                using (var frame = e.OpenSkeletonFrame())
                {
                    if (frame != null)
                    {
    
    
                        SkeletonFrame NUI_SKELETON_FRAME;
                         
                        
                        
                        
                        Skeleton[] skeletons = new Skeleton[frame.SkeletonArrayLength];
                        
    
                        if( SkeletonFrame.SkeletonData[1].eTrackingState == NUI_SKELETON_TRACKED )
                         }
    
    
    
                        frame.CopySkeletonDataTo(skeletons);
    
                        var skeleton = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault();
                       
    
                        if (skeleton != null)
                        {
                            double height = Height(skeleton);
                            Console.WriteLine("altezza " + height);
                        }
                    }
                }
            }
    
            private void MapJointsWithUIElement(Skeleton skeleton)
            {
                Console.WriteLine("disegno la mano sullo schermo");
                Point mappedPoint = this.ScalePosition(skeleton.Joints[JointType.Head].Position);
                    
              
                
                Canvas.SetLeft(righthand, mappedPoint.X);
                Canvas.SetTop(righthand, mappedPoint.Y);
                
                Console.WriteLine("posizione x: "+skeleton.Position.Y +" posizione y: "+skeleton.Position.Y+" posizione z: "+skeleton.Position.Z);
                
            }
    
            private Point ScalePosition(SkeletonPoint skeletonPoint)
            {
                DepthImagePoint depthPoint = this.sensor.CoordinateMapper.MapSkeletonPointToDepthPoint(skeletonPoint, DepthImageFormat.Resolution640x480Fps30);
                return new Point(depthPoint.X, depthPoint.Y);
            }
    
            void MainWindow_Unloaded(object sender, RoutedEventArgs e)
            {
    
                //stop the Sestor
    
                sensor.Stop();
    
    
    
            }
    
            public static double Length(Joint p1, Joint p2)
            {
                return Math.Sqrt(
                    Math.Pow(p1.Position.X - p2.Position.X, 2) +
                    Math.Pow(p1.Position.Y - p2.Position.Y, 2) +
                    Math.Pow(p1.Position.Z - p2.Position.Z, 2));
            }
            public static double Length(params Joint[] joints)
            {
                double length = 0;
    
                for (int index = 0; index < joints.Length - 1; index++)
                {
                    length += Length(joints[index], joints[index + 1]);
                }
    
    
                return length;
            }
    
            
    
            public static int NumberOfTrackedJoints(params Joint[] joints)
            {
                int trackedJoints = 0;
    
                foreach (var joint in joints)
                {
                    if (joint.TrackingState == JointTrackingState.Tracked)
                    {
                        trackedJoints++;
                    }
                }
    
    
                return trackedJoints;
            }
    
            public static double Height(Skeleton skeleton)
            {
                const double HEAD_DIVERGENCE = 0.1;
    
                var head = skeleton.Joints[JointType.Head];
                var neck = skeleton.Joints[JointType.ShoulderCenter];
                var spine = skeleton.Joints[JointType.Spine];
                var waist = skeleton.Joints[JointType.HipCenter];
                var hipLeft = skeleton.Joints[JointType.HipLeft];
                var hipRight = skeleton.Joints[JointType.HipRight];
                var kneeLeft = skeleton.Joints[JointType.KneeLeft];
                var kneeRight = skeleton.Joints[JointType.KneeRight];
                var ankleLeft = skeleton.Joints[JointType.AnkleLeft];
                var ankleRight = skeleton.Joints[JointType.AnkleRight];
                var footLeft = skeleton.Joints[JointType.FootLeft];
                var footRight = skeleton.Joints[JointType.FootRight];
    
    
                // Find which leg is tracked more accurately.
                int legLeftTrackedJoints = NumberOfTrackedJoints(hipLeft, kneeLeft, ankleLeft, footLeft);
                int legRightTrackedJoints = NumberOfTrackedJoints(hipRight, kneeRight, ankleRight, footRight);
    
    
                double legLength = legLeftTrackedJoints > legRightTrackedJoints ? Length(hipLeft, kneeLeft, ankleLeft, footLeft) : Length(hipRight, kneeRight, ankleRight, footRight);
    
    
                return Length(head, neck, spine, waist) + legLength + HEAD_DIVERGENCE;
            }
    
    
        }
    }
    

    Thursday, May 16, 2013 2:02 PM
  • There is sample code that you can use and leverage in the SDK. I recommend you look at that code and copy the sections that meet your needs.

    --Dale

    Thursday, May 16, 2013 8:08 PM
  • Thanks for your reply but i don't find this sample code. Can you help me?
    Friday, May 17, 2013 6:36 AM
  • I will not be able to write the code for you. This is an opportunity for you as a novice to learn C# through tutorials and sample code. I recommend you download the Kinect SDK toolkit and start learning from the simple examples like "Skeleton Basics".

    You might also have a good experiencing learning from the lessons and videos on Microsoft's Channel 9 about Kinect http://channel9.msdn.com/coding4fun/kinect?sort=viewed#tab_sortBy_viewed

    The SDK doc on floor data is http://msdn.microsoft.com/en-us/library/microsoft.kinect.skeletonframe.floorclipplane.aspx


    --Dale

    • Proposed as answer by arctorx Monday, May 20, 2013 9:08 AM
    Friday, May 17, 2013 1:17 PM