1

I am currently working on a project where it is necessary to track a joint's angle (the left knee) and display it live on a screen. I already have the skeleton drawn and a display window setup to overlay the skeleton on top of the person. I am programming in C# and using Visual Studio 2013 Ultimate.

I saw this link here kinect sdk 2.0 joint angles and tracking but the code keeps returning an error because the Results function at the bottom does not exist for me, and I cannot figure out why. Additionally, I am having trouble figuring out how to create a variable that can be displayed on the screen while updating constantly (if its not there it can display N/A or 0).

I also followed the link of the person answering to this page Display the angles of each joint of the skeleton in kinect c# but the code is meant for SDK 1.X.

Does anyone have example code or advice on how to fix the problem I am having with updating variables/defining Results so that I can use the code in the first example?

Community
  • 1
  • 1
Jicnon
  • 11
  • 1
  • 2
  • If someone knew how to make the code at the bottom of the first link work for constantly updating a variable that would be awesome, the Skeleton type doesnt exist in SDK 2.0 and I can't call Body.Joints – Jicnon Apr 02 '15 at 17:17

1 Answers1

2

Though I did not see your code or how you realized the person-tracking with overlaid skeleton, I recommend you reading the post series from Mike Taulty: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2014/11/04/kinect-for-windows-v2-sdk-hello-custom-gesture-world-part-3.aspx (this link is the 3rd post of this series, you find the links to #1 and #2 at the very top).

While he uses the GestureBuilder Beta to track the skeleton movements, for me this was a great starting point to get things running - especially speaking of the KINECT setup, event listeners etc., to get a feel of how the KINECT 2 gets its frames and gets hooked up in c# code. In part 2 he fills a control in his WPF application with a color, depending on how much the recorded gestures progress was detected, I think this could partly answer your question regarding a "live variable" on a screen.

Once you followed the tutorial and identified the relevant code parts for you, you realize you can (strictly speaking) throw away the OnGestureFrameArrived functionality, as you will need to modify the OnBodyFrameArrived method. In here you check for a trackedBody, if one is found, you can access its Joints and calculate their angle. I wrote the result to a console-window for debugging purposes, so finally you would write this result to a variable which is hooked up with a GUI element that display it.

 public void OnBodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
    {
        using (var frame = e.FrameReference.AcquireFrame())
        {
            if (frame != null)
            {
                frame.GetAndRefreshBodyData(this.bodies);

                var trackedBody = this.bodies.Where(b => b.IsTracked).FirstOrDefault();

                if (trackedBody != null)
                {
                        List<Joint> myJoints = new List<Joint>();
                        myJoints.Add(trackedBody.Joints[JointType.FootLeft]);
                        myJoints.Add(trackedBody.Joints[JointType.AnkleLeft]);
                        myJoints.Add(trackedBody.Joints[JointType.KneeLeft]);


                        if (myJoints.TrueForAll(x => x.TrackingState == TrackingState.Tracked))
                        {
                            Vector3D KneeLeft = new Vector3D(trackedBody.Joints[JointType.KneeLeft].Position.X, trackedBody.Joints[JointType.KneeLeft].Position.Y, trackedBody.Joints[JointType.KneeLeft].Position.Z);
                            Vector3D AnkleLeft = new Vector3D(trackedBody.Joints[JointType.AnkleLeft].Position.X, trackedBody.Joints[JointType.AnkleLeft].Position.Y, trackedBody.Joints[JointType.AnkleLeft].Position.Z);
                            Vector3D FootLeft = new Vector3D(trackedBody.Joints[JointType.FootLeft].Position.X, trackedBody.Joints[JointType.FootLeft].Position.Y, trackedBody.Joints[JointType.FootLeft].Position.Z);

                            Console.WriteLine("#1: " + AngleBetweenTwoVectors(AnkleLeft - KneeLeft, AnkleLeft - FootLeft));
                        }
                }
                else
                {
                    this.OnTrackingIdLost(null, null);
                }
            }
        }
    }

    public double AngleBetweenTwoVectors(Vector3D vectorA, Vector3D vectorB)
    {
        double dotProduct = 0.0;
        vectorA.Normalize();
        vectorB.Normalize();
        dotProduct = Vector3D.DotProduct(vectorA, vectorB);

        return (double)Math.Acos(dotProduct) / Math.PI * 180;
    }

TLDR-version: depending on how you handle your acquired kinect frames, you need to identify the correct event in your code, where a tracked body is found in a frame, in there you can look for the states of the different body joints and calculate the angles.


Further, if you want you can send me your code and I can try to hook this up for you, since your code would also be of interest to me.

konrad_pe
  • 1,189
  • 11
  • 26