Measuring a person’s height with Kinect

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

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 do not get any errors, but the fact is that it does not calculate my height correctly. I get numbers from 3 to 11 depending on how close I was to Kinect. What could be wrong? Is it all right that the number changes or it remains unchanged no matter what? Also why am I getting numbers like 11 (m)?

+2
source share
2 answers

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

Kinect SDK v1.x Skeletal Joints

Microsoft Kinect SDK v1.x Height Score

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

Suppose also that we have defined a function that can calculate the midpoint 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 for estimating user height might be the following (note that this is just pseudo-code):

 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 connections are well monitored , this algorithm works very well. However, it is possible (and this actually happens quite often) that some joints are excreted . On this page, from the MSDN documentation, you can see how to check if the joints have been moved to C #.

If a judgment is deduced, the chances of its wrong position increase. Thus, opportunities that rate height will also increase.

The following method can be used to check if all connections are tracked well. It returns false if at least one connection is not well monitored; 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 the user's height rating is to calculate it ONLY when all joints are well tracked.

In addition, we consider the possibility of always providing an average value of more than one of the last height values. For example, you can remember the last ten height values ​​in an array, and then provide each time the average value of these values. This will help reduce the impact of noise in your measures.

Your problem

Your code looks like a simplified version of the algorithm I just described. Therefore, the only reason you can get these strange values ​​is because tracking is not working. My suggestion is to try to use the above areJointsWellTracked method and evaluate the height only when all connections are well tracked.

Additional Note for Microsoft Kinect SDK v2

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

Kinect SDK v2 Skeletal Joints

Due to the different positions and definitions of some joints, the above algorithm for estimating 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 gauge user height using the Microsoft Kinect SDK v2 in this link .

+4
source

This link is useful to me.
User height accuracy

+1
source

Source: https://habr.com/ru/post/902904/


All Articles