这里是Kinect SDK 2.0的公式。完整项目可在https://github.com/jhealy/kinect2/tree/master/020-FaceNSkin_HowTallAmI中获取...
using System;
using Microsoft.Kinect;
public enum BodyHeightMeasurementSystem
{
Meters = 0, Imperial = 1
}
public static class BodyHeightExtension
{
public static BodyHeightMeasurementSystem MeasurementSystem = BodyHeightMeasurementSystem.Meters;
public static double Height( this Body TargetBody )
{
if ( TargetBody == null ) return -1.0;
if (TargetBody.IsTracked == false) return -2.0;
const double HEAD_DIVERGENCE = 0.1;
Joint _head = TargetBody.Joints[JointType.Head];
Joint _neck = TargetBody.Joints[JointType.Neck];
Joint _spine = TargetBody.Joints[JointType.SpineShoulder];
Joint _waist = TargetBody.Joints[JointType.SpineBase];
Joint _hipLeft = TargetBody.Joints[JointType.HipLeft];
Joint _hipRight = TargetBody.Joints[JointType.HipRight];
Joint _kneeLeft = TargetBody.Joints[JointType.KneeLeft];
Joint _kneeRight = TargetBody.Joints[JointType.KneeRight];
Joint _ankleLeft = TargetBody.Joints[JointType.AnkleLeft];
Joint _ankleRight = TargetBody.Joints[JointType.AnkleRight];
Joint _footLeft = TargetBody.Joints[JointType.FootLeft];
Joint _footRight = TargetBody.Joints[JointType.FootRight];
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);
double _retval = Length(_head, _neck, _spine, _waist) + legLength + HEAD_DIVERGENCE;
if (MeasurementSystem == BodyHeightMeasurementSystem.Imperial) _retval = MetricHelpers.MetersToFeet(_retval);
return _retval;
}
public static double UpperHeight( this Body TargetBody )
{
Joint _head = TargetBody.Joints[JointType.Head];
Joint _neck = TargetBody.Joints[JointType.SpineMid];
Joint _spine = TargetBody.Joints[JointType.SpineShoulder];
Joint _waist = TargetBody.Joints[JointType.SpineBase];
return Length(_head, _neck, _spine, _waist);
}
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));
}
public static double Length(params Joint[] joints)
{
double length = 0;
for (int index = 0; index < joints.Length - 1; index++)
{
length += Length(joints[index], joints[index + 1]);
}
return length;
}
public static int NumberOfTrackedJoints(params Joint[] joints)
{
int trackedJoints = 0;
foreach (var joint in joints)
{
if ( joint.TrackingState== TrackingState.Tracked )
{
trackedJoints++;
}
}
return trackedJoints;
}
public static Joint ScaleTo(Joint joint, int width, int height, float MaxX, float MaxY)
{
Microsoft.Kinect.CameraSpacePoint position = new Microsoft.Kinect.CameraSpacePoint()
{
X = Scale(width, MaxX, joint.Position.X),
Y = Scale(height, MaxY, -joint.Position.Y),
Z = joint.Position.Z
};
joint.Position = position;
return joint;
}
public static Joint ScaleTo(Joint joint, int width, int height)
{
return ScaleTo(joint, width, height, 1.0f, 1.0f);
}
private static float Scale(int maxPixel, float maxBody, float position)
{
float value = ((((maxPixel / maxBody ) / 2) * position) + (maxPixel / 2));
if (value > maxPixel)
{
return maxPixel;
}
if (value < 0)
{
return 0;
}
return value;
}
}