0

I am working on Kinect for my research project . I have worked previously to calculate the joint angle of kinect and the joint coordinates. I would like to calculate the center of mass of the body which is being tracked. Any idea would be appreciated and code snippets would be immensely helpful. I owe a lot to stack overflow without the community help it would had not been possible to do such a thing. Thanks in Advance Please find the code where i want to include this center of mass function. This function tracks the skeleton.

Skeleton GetFirstSkeleton(AllFramesReadyEventArgs e) { using (SkeletonFrame skeletonFrameData = e.OpenSkeletonFrame()) { if (skeletonFrameData == null) { return null; }

            skeletonFrameData.CopySkeletonDataTo(allSkeletons);

            //get the first tracked skeleton
            Skeleton first = (from s in allSkeletons
                              where s.TrackingState == SkeletonTrackingState.Tracked
                              select s).FirstOrDefault();
            return first;
        }

I have tried using this code in my code but its not getting accustomed , can any one please help me include the center of mass code.

oreach (SkeletonData data in skeletonFrame.Skeletons) {

SkeletonFrame allskeleton = e.SkeletonFrame;

            // Count passive and active person up to six in the group  

            int numberOfSkeletonsT = (from s in allskeleton.Skeletons

                                      where s.TrackingState == SkeletonTrackingState.Tracked  select s).Count();

            int numberOfSkeletonsP = (from s in allskeleton.Skeletons  

where s.TrackingState == SkeletonTrackingState.PositionOnly select s).Count();

            // Count passive and active person up to six in the group

            int totalSkeletons = numberOfSkeletonsP + numberOfSkeletonsT;

            //Console.WriteLine("TotalSkeletons = " + totalSkeletons);

//======================================================

if (data.TrackingState == SkeletonTrackingState.PositionOnly)

            {

foreach (Joint joint in data.Joints)

                {

                    if (joint.Position.Z != 0)

                    {

double centerofmassX = com.Position.X;

                        double centerofmassY = com.Position.Y;

                        double centerofmassZ = com.Position.Z;

   Console.WriteLine( centerofmassX +  centerofmassY + centerofmassZ );

                    }

            }

1 Answers1

0

See a couple of resources here:

  1. http://mathwiki.ucdavis.edu/Calculus/Vector_Calculus/Multiple_Integrals/Moments_and_Centers_of_Mass#Three-Dimensional_Solids
  2. http://www.slideshare.net/GillianWinters/center-of-mass-presentation
  3. http://en.wikipedia.org/wiki/Locating_the_center_of_mass

Basically no matter what, you are going to need to find the mass of your user. This can be a simple input, then you can determine how much weight the person puts on each foot and use the equations described at all of these sources. Another option may be to use plumb lines on a planar shape representation of the user in 2D, However that won't be the actually accurate 3D center of mass.

Here is an example of how to find what amount of mass is on each foot. using the equation found on http://www.vitutor.com/geometry/distance/line_plane.html

Vector3 v = new Vector3(skeleton.Joints[JointType.Head].Position.X,    skeleton.Joints[JointType.Head].Position.Y, skeleton.Joints[JointType.Head].Position.Z);
double mass;
double leftM, rightM;

double A = sFrame.FloorClipPlane.X,
B = sFrame.FloorClipPlane.Y,
C = sFrame.FloorClipPlane.Z;

//find angle
double angle = Math.ASin(Math.Abs(A * v.X + B * v.Y * C * v.Z)/(Math.Sqrt(A * A + B * B + C * C) * Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z)));

if (angle == 90.0)
{
     leftM = mass / 2.0;
     rightM = mass / 2.0;
}

double distanceFrom90 = 90.0 - angle;

if (distanceFrom90 > 0)
{
    double leftMultiple = distanceFrom90 / 90.0;
    leftM = mass * leftMultiple;
    rightM = mass - leftM;
}

else
{
    double rightMultiple = distanceFrom90 / 90.0;
    rightM = rightMultiple * mass;
    leftM = mass - rightMultiple;
}

This is of course assuming that the user is on both feet, but you could modify the code to create a new plane based off the users feet instead of the automatic one generated by Kinect.

The code to then find the center of mass you have to choose a datum. I would choose the head as that is the top of the person, and you can measure down from it easily. Using the steps found here:

double distanceFromDatumLeft = Math.Sqrt(Math.Pow(headX - footLeftX, 2) + Math.Pow(headY - footLeftY, 2) + Math.Pow(headZ - footLeftZ, 2));
double distanceFromDatumLeft = Math.Sqrt(Math.Pow(headX - footRightX, 2) + Math.Pow(headY - footRightY, 2) + Math.Pow(headZ - footRightZ, 2));

double momentLeft = distanceFromDatumLeft * leftM;
double momentRight = distanceFromDatumRight * rightM;

double momentSum = momentLeft + momentRight;

//measured in units from the datum
double centerOfGravity = momentSum / mass;

You then can of course show this on the screen by passing a point to plot that is centerOfGravity points below the head.

Liam McInroy
  • 4,339
  • 5
  • 32
  • 53
  • Thank you for the feedback. I may sound novice for this case ,but how do we determine the weight person puts on each foot , because kinect only allows us to track, not measure weight. And another question is How do I include it in my code. Please help me in coding this center of Mass in the first code snippet that is present . Thanks in advance for the help. – user2823510 Feb 25 '14 at 07:49
  • @user2823510 Check edits, you still have to write the code for mass on your own, but this should get you started – Liam McInroy Feb 25 '14 at 23:43
  • Hey Outlaw Lemur, thank you for providing a great insight how should it work to calculate the mass. – user2823510 Mar 22 '14 at 09:27
  • Outlaw Lemur you are just fantastic with so much logic and help.Can I ask you one more stuff.I have this Kinect camera up and running and it is able to calculate the joint angles of skeleton of subject. But the problem starts when I try to calculate the joint angles by placing the kinect camera on the side of user(left side specifically or right side you can consider any)the data that that I am getting after using the same algorithm and code for the calculation from side view camera the values that I am getting is messed up. Its not giving correct values as the Kinect in front of the user – user2823510 Mar 22 '14 at 20:31
  • @user2823510 First, if I helped you I am happy and you can accept this answer:)... second, see http://stackoverflow.com/questions/10192476/kinect-sideways-skeleton-tracking/10260664#10260664 You can see that sideways skeletal tracking does not work very well with Kinect – Liam McInroy Mar 23 '14 at 03:13