Measuring person's height using Kinect

守給你的承諾、 提交于 2019-12-21 21:29:17

问题


I am trying to calculate the height of a person using Kinect. Here is how I calculate the height (this code is not very sophisticated, it is only for testing purposes):

double h2s =  Math.Sqrt(Math.Pow(headX - shoulderCenterX, 2) + Math.Pow(headY - shoulderCenterY, 2)+ Math.Pow(headZ - shoulderCenterZ, 2));
double s2hip =  Math.Sqrt(Math.Pow(shoulderCenterX - hipX, 2) + Math.Pow(shoulderCenterY - hipY, 2) + Math.Pow(shoulderCenterZ - hipZ, 2));
double hip2Lhip =  Math.Sqrt(Math.Pow(hipX - hipLeftX, 2) + Math.Pow(hipY - hipLeftY, 2) + Math.Pow(hipZ - hipLeftZ, 2));
double Lhip2kneeL =  Math.Sqrt(Math.Pow(hipLeftX - kneeLeftX, 2) + Math.Pow(hipLeftY - kneeLeftY, 2) + Math.Pow(hipLeftZ - kneeLeftZ, 2));
double kneeL2ankle = Math.Sqrt(Math.Pow(kneeLeftX - ankleLeftX, 2) + Math.Pow(kneeLeftY - ankleLeftY, 2) + Math.Pow(kneeLeftZ - ankleLeftZ, 2));

double heigth = h2s + s2hip + hip2Lhip + Lhip2kneeL + kneeL2ankle;

vyskatextbox.Text = heigth.ToString();

I am not getting any error, but the thing is that it is calculating my height wrong. I am getting numbers between 3 to 11 depending on how close I was to Kinect. What could be wrong? Is it all right that the number changes or should it stay the same no matter what? Also why do I get numbers like 11 (m)?


回答1:


I see a shoulderCenter in your code, so you are probably using the Microsoft Kinect SDK v1.x. In this case, the skeletal joints are the following ones:

Height estimation in Microsoft Kinect SDK v1.x

Assume that we have a function that can calculate the distance between two joints. We name this function d(joint1, joint2).

Assume also that we have defined a function which can calculate the average point between two joints (note that the following is just pseudocode):

function avg(joint1, joint2) {
    avg_joint.x = (joint1.x + joint2.x) / 2.0;
    avg_joint.y = (joint1.y + joint2.y) / 2.0;
    avg_joint.z = (joint1.z + joint2.z) / 2.0;
    return avg_joint;
}

A good algorithm to estimate the user's height can be the following one (note that it is just a pseudocode):

torso_height = d(HEAD, SHOULDER_CENTER) +
               d(SHOULDER_CENTER, SPINE) +
               d(SPINE, HIP_CENTER) +
               d(HIP_CENTER, avg(HIP_RIGHT, HIP_LEFT));

left_leg_height = d(HIP_LEFT, KNEE_LEFT) +
                  d(KNEE_LEFT, ANKLE_LEFT) +
                  d(ANKLE_LEFT, FOOT_LEFT);

right_leg_height = d(HIP_RIGHT, KNEE_RIGHT) +
                   d(KNEE_RIGHT, ANKLE_RIGHT) +
                   d(ANKLE_RIGHT, FOOT_RIGHT);

tot_height = torso_height +
             (left_leg_height + right_leg_height) / 2.0;

If all joints are well tracked, this algorithm works pretty well. However, it is possible (and it actually happens quite often) that some joints are inferred. In this page from the documentation on MSDN, you can see how to test if joints are inferred in C#.

If a joint is inferred, the possibilities that its position is wrong increase. And so the possibilities that height estimation will fail increases too.

The following method can be used to test if all joints are well tracked. It returns false if at least one joint is not well tracked; otherwise it returns true:

function areJointsWellTracked(JointCollection joints)
{
    foreach (Joint joint in joints)
        if(joint.TrackingState != JointTrackingState.Tracked)
            return false;

    return true;
}

So what you can do to improve user's height estimation is to calculate it ONLY when all joints are well tracked.

Moreover, consider the possibility to provide always the average of more than one of the last height values. For instance, you can memorize the last ten height values in an array, and then provide everytime the average of these values. This will help to reduce the effect of noise in your measures.

Your problem

Your code seems to be a simplified version of the algorithm that I have just described. So the only reason why you can get those strange values are that tracking is not working well. My suggestion is to try to use the aforementioned areJointsWellTracked method, and estimate the height only when all joints are well tracked.

Additional note for Microsoft Kinect SDK v2

For developers that are using SDK v2, note that skeletal joints are not defined as in SDK v1.x. The following image shows this difference:

Due to the different positions and definitions of some joints, the above algorithm to evaluate the height should be edited as follows:

torso_height = d(HEAD, NECK)+
               d(NECK, SPINE_SHOULDER) +
               d(SPINE_SHOULDER, SPINE_MID) +
               d(SPINE_MID, SPINE_BASE) +
               d(SPINE_BASE, avg(HIP_RIGHT, HIP_LEFT));

left_leg_height = d(HIP_LEFT, KNEE_LEFT) +
                  d(KNEE_LEFT, ANKLE_LEFT) +
                  d(ANKLE_LEFT, FOOT_LEFT);

right_leg_height = d(HIP_RIGHT, KNEE_RIGHT) +
                   d(KNEE_RIGHT, ANKLE_RIGHT) +
                   d(ANKLE_RIGHT, FOOT_RIGHT);

tot_height = torso_height +
             (left_leg_height + right_leg_height) / 2.0;

You can find an interesting discussion on how to evaluate user's height with Microsoft Kinect SDK v2 at this link.




回答2:


this link was helpful to me.
Find user height accurately



来源:https://stackoverflow.com/questions/30462391/measuring-persons-height-using-kinect

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!