There are actually many ways to measure height Using Kinect:
The first method is to use the field of view angle of Kinect and some triangle geometric operations to roughly measure the height of the object, which was mentioned in the previous introduction to deep image processing.
The second method is to use the coordinates of the 20 key nodes provided by the Kinect skeleton tracking to measure the height of the human body based on a certain algorithm. Here is a sharing of the example above channel9. Here, based on the similarity between the arm and height, I have made some extensions to this example to calculate the width of the arm, in fact, the advantage of calculating height with an arm scale is that normal mode (normal model, 20 nodes) can be used, and the sitting posture mode (seat model, 10 nodes) can be used ), in this way, you can measure the height, but the accuracy is not guaranteed. This is just an idea.
I. height calculation algorithm
The skeleton data obtained by Kinect contains x, y, and zcoordinate information of 20 nodes. You may wonder why you do not directly calculate the height by using the distance between the head joint points and the toe joint points. This is not accurate because the user may not be standing straight. If so, the error is relatively large.
Another problem is that the header is given the position of the center point of the header. If this position is used, you need to increase the number by 9 to 11 cm. However, even so, the accuracy cannot reach 100%, to be more precise, you may need to use a Deep Image value to extract the top position of the header. It does not need to be so troublesome. Now let's take a look at how we can use the skeleton to close the node to calculate the height information.
Observe the following skeleton points and you can see that height can be composed of the following parts (middle red ):
• Head-shouldercenter)
• Shouldercenter-spine)
• Spine-hip center)
• Hipcenter-left or right knee joint (kneeleft or kneeright)
• Left knee kneeleft (right knee kneeright)-left ankle leleft (right ankle ankleright)
• Left ankle leleft (right ankle ankleright)-left ankle footleft (right ankle footright)
You can use the arm scale to calculate the height or the nodes shown in green in the figure:
• Left Hand (headleft)-left wrist (wrist left)
• Left wrist (wrist left)-left elbow (elbow left)
• Left elbow (elbow left)-left shoulder (shoulder left)
• Shoulder left-shoulder Center)
• Shoulder center-shoulder right)
• Shoulder right-elbow right)
• Right elbow right-wrist right)
• Right wrist (wrist right)-Right hand (hand right)
The principle is as follows. We will compile the code below for implementation.
II. Implementation
The program interface is very simple. It shows 20 nodes and then displays the calculation result. There are several notes:
First, the location information of the nodes is three-dimensional. The following formula is used to calculate the distance between the two nodes.
public static double Length(Joint p1, Joint p2){ return Math.Sqrt( Math.Pow(p1.Position.X - p2.Position.X, 2) + Math.Pow(p1.Position.Y - p2.Position.Y, 2) + Math.Pow(p1.Position.Z - p2.Position.Z, 2));}
The above code is very direct. Step 2: We should use the left leg or right leg for more accurate measurement. We use the best tracking. The following code calculates the number of tracking points in the leg. If the number is large, use that one.
public static int NumberOfTrackedJoints(params Joint[] joints){ int trackedJoints = 0; foreach (var joint in joints) { if (joint.TrackingState == JointTrackingState.Tracked) { trackedJoints++; } } return trackedJoints;}
Using the above function, we can determine whether to use the left leg or the right leg.
// Find which leg is tracked more accurately.int legLeftTrackedJoints = NumberOfTrackedJoints(hipLeft, kneeLeft, ankleLeft, footLeft);int legRightTrackedJoints = NumberOfTrackedJoints(hipRight, kneeRight, ankleRight, footRight);double legLength = legLeftTrackedJoints > legRightTrackedJoints ? Length(hipLeft, kneeLeft, ankleLeft, footLeft) : Length(hipRight, kneeRight, ankleRight, footRight);
Then we use the extension method to calculate the height of the skeleton. The code for the method is as follows:
public static double Height(this Skeleton skeleton){ const double HEAD_DIVERGENCE = 0.1; var head = skeleton.Joints[JointType.Head]; var neck = skeleton.Joints[JointType.ShoulderCenter]; var spine = skeleton.Joints[JointType.Spine]; var waist = skeleton.Joints[JointType.HipCenter]; var hipLeft = skeleton.Joints[JointType.HipLeft]; var hipRight = skeleton.Joints[JointType.HipRight]; var kneeLeft = skeleton.Joints[JointType.KneeLeft]; var kneeRight = skeleton.Joints[JointType.KneeRight]; var ankleLeft = skeleton.Joints[JointType.AnkleLeft]; var ankleRight = skeleton.Joints[JointType.AnkleRight]; var footLeft = skeleton.Joints[JointType.FootLeft]; var footRight = skeleton.Joints[JointType.FootRight]; // Find which leg is tracked more accurately. int legLeftTrackedJoints = NumberOfTrackedJoints(hipLeft, kneeLeft, ankleLeft, footLeft); int legRightTrackedJoints = NumberOfTrackedJoints(hipRight, kneeRight, ankleRight, footRight); double legLength = legLeftTrackedJoints > legRightTrackedJoints ? Length(hipLeft, kneeLeft, ankleLeft, footLeft) : Length(hipRight, kneeRight, ankleRight, footRight); return Length(head, neck, spine, waist) + legLength + HEAD_DIVERGENCE;}
Similarly, we use nine knots, including hands, wrists, elbows, shoulders, and so on, to calculate the arm scale and approximate height using the arm scale, the following extension method named armextendwith is the calculation arm expansion method.
public static double ArmExtendWith(this Skeleton skeleton){ var armWidthDeviation = 0.5; var handRight = skeleton.Joints[JointType.HandRight]; var wristRight = skeleton.Joints[JointType.WristRight]; var elowRight = skeleton.Joints[JointType.ElbowRight]; var shoulderRight = skeleton.Joints[JointType.ShoulderRight]; var shoulderCenter = skeleton.Joints[JointType.ShoulderCenter]; var handleft = skeleton.Joints[JointType.HandLeft]; var wristleft = skeleton.Joints[JointType.WristLeft]; var elowleft = skeleton.Joints[JointType.ElbowLeft]; var shoulderleft = skeleton.Joints[JointType.ShoulderLeft]; // Calculate the left and right arm extends width double rightArmExtendsWidth = Length(handRight, wristRight, elowRight, shoulderRight, shoulderCenter); double leftArmExtendsWidth = Length(handleft, wristleft, elowleft, shoulderleft, shoulderCenter); return rightArmExtendsWidth + leftArmExtendsWidth + armWidthDeviation;}
Finally, call this method in the skeletonframeready event.
void Sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e){ using (var frame = e.OpenSkeletonFrame()) { if (frame != null) { canvas.Children.Clear(); Skeleton[] skeletons = new Skeleton[frame.SkeletonArrayLength]; frame.CopySkeletonDataTo(skeletons); var skeleton = skeletons.Where(s => s.TrackingState == SkeletonTrackingState.Tracked).FirstOrDefault(); if (skeleton != null) { // Calculate height. double height = Math.Round(skeleton.Height(), 2); double armExtendsWidth = Math.Round(skeleton.ArmExtendWith(), 2); // Draw skeleton joints. foreach (JointType joint in Enum.GetValues(typeof(JointType))) { DrawJoint(skeleton.Joints[joint].ScaleTo(640, 480)); } // Display height. tblHeight.Text = String.Format("Height: {0} m", height); tblArmExtendWidth.Text = String.Format("ArmWidth: {0} m", armExtendsWidth); } } }}
Now you can run the code to view the results.
Iii. Conclusion
This article introduces two methods for measuring height by Using Kinect. One is the previous method, which uses the field of view and the triangular relationship between the object, and uses geometric operations to measure the height of the object, the second approach is to use the bone data provided by Kinect to calculate the height of the human body based on the direct distance between the nodes. This article focuses on two ways to calculate the height by using the distance between the nodes of the skeleton, one is the length of 8 knots, including the head, spine, hip joint, knee joint, and ankle joint, shared in channel9, to calculate the height, and the other is related to the boom, hand, wrist, elbow, shoulder, and other nine close node information, compared to the first method, this method can be calculated using the Sitting Posture mode, meaning that you can measure the height when sitting. Of course, the accuracy may not be very accurate. This article only provides some ideas about how to measure the height of the Kinect. Click here to download the source code. I hope this article will help you!