1

Sorry about this but I need some conformation about this function and calculation

I currently have these Vectors:

   Vector3D ElbowLeft = new Vector3D(body.Joints[JointType.ElbowLeft].Position.X, body.Joints[JointType.ElbowLeft].Position.Y, body.Joints[JointType.ElbowLeft].Position.Z);
   Vector3D WristLeft = new Vector3D(body.Joints[JointType.WristLeft].Position.X, body.Joints[JointType.WristLeft].Position.Y, body.Joints[JointType.WristLeft].Position.Z);
   Vector3D ShoulderLeft = new Vector3D(body.Joints[JointType.ShoulderLeft].Position.X, body.Joints[JointType.ShoulderLeft].Position.Y, body.Joints[JointType.ShoulderLeft].Position.Z);

   Vector3D Head = new Vector3D(body.Joints[JointType.Head].Position.X, body.Joints[JointType.Head].Position.Y, body.Joints[JointType.Head].Position.Z);
   Vector3D Neck = new Vector3D(body.Joints[JointType.Neck].Position.X, body.Joints[JointType.Neck].Position.Y, body.Joints[JointType.Neck].Position.Z);
   Vector3D SpineShoulder = new Vector3D(body.Joints[JointType.SpineShoulder].Position.X, body.Joints[JointType.SpineShoulder].Position.Y, body.Joints[JointType.SpineShoulder].Position.Z);

I am calculating the angle between the two vectors using this function

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;
}

And I am calling it like this:

   double LeftElbowAngle = AngleBetweenTwoVectors(ElbowLeft - ShoulderLeft, ElbowLeft - WristLeft);
   double NeckAngle = AngleBetweenTwoVectors(Neck - Head, Neck - SpineBase);

Is this correct? Im just doubting myself because When i put my arm straight or stand up straight it detects an angle of about 170 - 175 rather than 180. on both my neck and my elbow joint

  • Remember that you have 3 dimensions there, getting the arm or head perfectly straight might not be very easy. How does the other angles look? – Chris Apr 23 '15 at 20:08
  • Well Left/Right Elbow joint is 170-178ish, with what seems to me to be a straight arm. Neck is also about the same when I stand perfectly straight. Same with the Knees for the leg. And I haven't figured out how to do wrist calculations since the Kinect also connects the wrist to the thumb... My friend helped me confirm that everything is mathematically correct. – ShatteredPheonix Apr 23 '15 at 20:11
  • How about 45, 90 & 135 degrees? Looks alright? – Chris Apr 23 '15 at 20:12
  • Yea again when I move my arm to what seems like a right angle it fluctuates between 80-90. Same for 45, they seem mostly to fluctuate by 10. Like when I put my arm completely straight it won't give me something weird like 120. – ShatteredPheonix Apr 23 '15 at 20:15
  • Sounds like it's working fine then. I would guess the kinects depth accuracy is simply not good enough to give you a perfectly straight 3D line. It might also be hard for it to actually track the elbow joint very well if the arm is perfectly straight. – Chris Apr 23 '15 at 20:18
  • Yea I just wanted to make sure that my maths wasn't wrong anywhere. I'm guess it's different for every individual depending on their bones structure and such. Now I face a different problem of how to only track 1 user, and stack overflow has the question posted but no good answer. So I don't really want to post the same question again. – ShatteredPheonix Apr 23 '15 at 20:21
  • Looks like you should be able to assign an id to a skeleton: http://stackoverflow.com/questions/21965723/kinect-how-do-i-id-the-first-tracked-skeleton-and-do-stuff-with-it-after/21972949#21972949 – Chris Apr 23 '15 at 20:24
  • I'm fairly certain that's for the Kinect 1.0. I'm using V2 with SDK 2.0 so it's slightly different but i will try non the less – ShatteredPheonix Apr 23 '15 at 20:27
  • Ah ok. Never actually tried any of that myself. – Chris Apr 23 '15 at 20:27
  • You should seems like you would be really good at it. Better than me at least. – ShatteredPheonix Apr 23 '15 at 20:28

2 Answers2

1

I have confirmed that the above Algorithim is correct mathematically, however the accuracy of the device may be a bit off due to the hardware, and individual human bones may prevent from perfect joint extension which is 180.

0

correct me If I'm wrong but I think instead of this return (double)Math.Acos(dotProduct) / Math.PI * 180 it should be

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

since angle returned by Math.Acos is in radian and to convert it into degrees you should be multiplying it to 180/pi

mudassir ahmed
  • 191
  • 1
  • 1
  • 13