none
Using Kinect to calculate angles between Human Body joints RRS feed

  • Question

  • Hello,

    So i'm trying to use kinect to get the joint angles of a human body .For example the angle between the Upper part of the arm and the Lower part ,so technically the elbow joint angle .I only need on axis angle ,so i only need the angle i would get if say the user stood Parallel  to the camera.

    Also attaching a rough sketch if what i want to achieve .


    Thanks in Advance. 


    Thursday, September 8, 2011 1:34 PM

Answers

  • I'm pretty sure that you intend to use the left elbow with the left shoulder and the left wrist, but right now you're using the right elbow.

    Also, to get the correct angle with elbow at origin and not the mirror image (although in this particular case it seems inconsequential) I think you'd want to do

    Vector3 b1 =a3-a1;
    Vector3 b2=a2-a1;
    

    Also, you need to normalize the dot product before doing the call to Math.Acos:

    AngleBetweenTwoVectors(Vector3.Normalize(b1), Vector3.Normalize(b2)).ToString();
    

    Eddy


    I'm here to help
    Thursday, September 8, 2011 10:21 PM

All replies

  • Do you mean that you only need the elbow joint angle component in Y-Z plane? The Kinect SDK gives you positions of right wrist, left wrist, right elbow, left elbow, right shoulder and left shoulder as part of SkeletonData.Joints structure (in managed code, let me know if you're using C++ and I'll adapt examples).

    Specifically, to get position of right wrist, you would do:

    SkeletonData skeleton = <obtained from some skeleton frame>;
    Microsoft.Research.Kinect.Nui.Vector rightHand = skeleton.Joints[JointID.WristRight].Position;

    so if you obtain positions of right wrist, elbow and shoulder in this way you should be able to compute angle by calculating the elbow-wrist direction vector and the elbow-shoulder direction vector and then using the standard vector dot product formula (http://en.wikipedia.org/wiki/Dot_product).

    Does that help?
    Eddy


    I'm here to help
    Thursday, September 8, 2011 6:47 PM
  • Thank you for the relpy.

    I;m using C# and i know about the positions and also tried calculating the dot product the thing is that if i like stand perfectly straight in from of the Kinect the angle of my elbow should be like 180 degrees right  ? But the dot product method yields different results .Or am i missing something here
    Artyom Topchyan
    Thursday, September 8, 2011 8:16 PM
  • can you show me your code for calculating elbow angle?

    Eddy


    I'm here to help
    Thursday, September 8, 2011 8:44 PM
  •  

    Something like this
    	
       Vector3 a1 = new Vector3(user.Joints[JointID.ElbowRight].Position.X, user.Joints[JointID.ElbowRight].Position.Y, user.Joints[JointID.ElbowRight].Position.Z);
        Vector3 a2 = new Vector3(user.Joints[JointID.ShoulderLeft].Position.X, user.Joints[JointID.ShoulderLeft].Position.Y, user.Joints[JointID.ShoulderLeft].Position.Z);
        Vector3 a3 = new Vector3(user.Joints[JointID.WristLeft].Position.X, user.Joints[JointID.WristLeft].Position.Y, user.Joints[JointID.WristLeft].Position.Z);
    
                        Vector3 b1 =a1-a3;
                        Vector3 b2=a1-a2;
                        AngleBetweenTwoVectors(b1, b2).ToString();
    
    public float AngleBetweenTwoVectors(Vector3 vectorA, Vector3 vectorB)
            {
                float dotProduct = 0.0f;
              dotProduct=  Vector3.Dot( vectorA,  vectorB );
    
              return (float)Math.Acos(dotProduct); 
            }
    

    _

     


    Artyom Topchyan

    Thursday, September 8, 2011 9:10 PM
  • I'm pretty sure that you intend to use the left elbow with the left shoulder and the left wrist, but right now you're using the right elbow.

    Also, to get the correct angle with elbow at origin and not the mirror image (although in this particular case it seems inconsequential) I think you'd want to do

    Vector3 b1 =a3-a1;
    Vector3 b2=a2-a1;
    

    Also, you need to normalize the dot product before doing the call to Math.Acos:

    AngleBetweenTwoVectors(Vector3.Normalize(b1), Vector3.Normalize(b2)).ToString();
    

    Eddy


    I'm here to help
    Thursday, September 8, 2011 10:21 PM
  • Ok thank you it works...damn cant believe i forgot the to normalize the vector and misspelled joint names.

     


    Artyom Topchyan
    Thursday, September 8, 2011 10:38 PM
  • First time posting here so first, thanks Eddy and others for your contributions. I've gained a lot from them. 

    I was wondering though if this method is the same way to calculate bone ZXY rotations for storage in the BVH file hierarchy. If not, please could anyone explain how. Thanks.

     

    Saturday, September 10, 2011 4:47 PM
  • Hey there,

    how did you activate Vector3 in your code?

     

    Thank you in advance

    (I know Vector3 from xna but i cant add an xna reference...)

    Monday, September 12, 2011 11:32 AM
  • Flamme,

    If you can point me to good documentation regarding BVH file hierarchy, I can read it and let you know whether this method for calculating angles corresponds to the angles expected in the BVH format. Otherwise, I have no idea.

    Eddy


    I'm here to help
    Monday, September 12, 2011 6:47 PM
  • Hi Eddy,

    Hadn't checked here for a while. Thanks for your reply. Here is a link explaining the structure. http://www.cmis.brighton.ac.uk/staff/alb14/ci219/lectures%20&%20tutorials/assets/BVH.rtf  I gathered the rotational data are Euler values (xyz). Please go through- looking forward to your take on it. Thanks.

    Fllamme.


    • Edited by Flamme Saturday, September 24, 2011 12:49 AM
    Saturday, September 24, 2011 12:48 AM
  • It looks like you should be able to obtain a BVH kind of representation from the data provided by kinect, but you'd have to calculate the rotations yourself. The code above will only give you angle between two vectors that correspond to adjacent joint-to-joint connections, and to obtain separate values for X vs Y vs Z rotation angles for each joint you would need to calculate angles of rotation against more than just one reference vector.

    It's basically the same math, but with more components, and also keeping in mind that BVH structure is hierarchical.

    Eddy


    I'm here to help
    Saturday, September 24, 2011 2:23 AM
  • Hey Eddy,

     

    I was looking at your response and had a question.  How would you calculate the angles of rotation against more than one reference vector?  Also, would you just need to calculate it against the all other joints in the hierarchy?  All your help would be greatly appreciated!

     

    Stephen

    Wednesday, October 26, 2011 7:05 PM
  • Hi,

    i had the same problem. Thanks for the help.

     

    I want to Display the resulting angle next to my Videoframe. How can I do this? So that the angle ist displayed for every frame that kinect delivers. (no saving so far, just displaying).

    public float AngleBetweenTwoVectors(Vector3 b1, Vector3 b2)
            {
    
                AngleBetweenTwoVectors(Vector3.Normalize(b1), Vector3.Normalize(b2)).ToString();
                float dotProduct = 0.0f;
                dotProduct = Vector3.Dot(b1, b2);
    
                double OUT= Math.Acos(dotProduct);
                return (float)Math.Acos(dotProduct);
    
            }
    


    In my case its "OUT" what should be displayed next to the Videoframe.

    THANKS =)

     

    Friday, November 11, 2011 5:38 PM
  • Hey there..... i have tried to get the depth data and it worked fine.... but now i want to find out the angles between the joints... i'm a beginner in this regard...any detailed explanation would be highly grateful.

    and also... is vector3 some kind of basic function ?? or do we have to assign a particular  object for every angle we calculate ?

     
    Tuesday, April 15, 2014 11:34 AM
  • do these work for the new sdk ?? ie., SDK 1.8 ??
    Tuesday, April 15, 2014 11:34 AM