虽然我没有看到您的代码或您如何实现覆盖骨架的人员跟踪,但我建议您阅读 Mike Taulty 的系列文章:http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2014/11/04/kinect-for-windows-v2-sdk-hello-custom-gesture-world-part-3.aspx(此链接是本系列的第 3 篇文章,您可以找到链接到顶部的 #1 和 #2)。
虽然他使用 GestureBuilder Beta 来跟踪骨架运动,但对我来说,这是一个很好的起点,可以让事情运行起来 - 特别是谈到 KINECT 设置、事件侦听器等,以了解 KINECT 2 的运行情况它的框架并连接到 c# 代码中。在第 2 部分中,他在其 WPF 应用程序中使用颜色填充控件,具体取决于检测到记录的手势进度,我认为这可以部分回答您关于屏幕上“实时变量”的问题。
一旦您按照教程确定了相关的代码部分,您就会意识到您可以(严格来说)放弃 OnGestureFrameArrived 功能,因为您需要修改 OnBodyFrameArrived 方法。在这里你检查一个 trackedBody,如果找到,你可以访问它的关节并计算它们的角度。出于调试目的,我将结果写入控制台窗口,所以最后您可以将此结果写入一个变量,该变量与显示它的 GUI 元素挂钩。
public void OnBodyFrameArrived(object sender, BodyFrameArrivedEventArgs e)
{
using (var frame = e.FrameReference.AcquireFrame())
{
if (frame != null)
{
frame.GetAndRefreshBodyData(this.bodies);
var trackedBody = this.bodies.Where(b => b.IsTracked).FirstOrDefault();
if (trackedBody != null)
{
List<Joint> myJoints = new List<Joint>();
myJoints.Add(trackedBody.Joints[JointType.FootLeft]);
myJoints.Add(trackedBody.Joints[JointType.AnkleLeft]);
myJoints.Add(trackedBody.Joints[JointType.KneeLeft]);
if (myJoints.TrueForAll(x => x.TrackingState == TrackingState.Tracked))
{
Vector3D KneeLeft = new Vector3D(trackedBody.Joints[JointType.KneeLeft].Position.X, trackedBody.Joints[JointType.KneeLeft].Position.Y, trackedBody.Joints[JointType.KneeLeft].Position.Z);
Vector3D AnkleLeft = new Vector3D(trackedBody.Joints[JointType.AnkleLeft].Position.X, trackedBody.Joints[JointType.AnkleLeft].Position.Y, trackedBody.Joints[JointType.AnkleLeft].Position.Z);
Vector3D FootLeft = new Vector3D(trackedBody.Joints[JointType.FootLeft].Position.X, trackedBody.Joints[JointType.FootLeft].Position.Y, trackedBody.Joints[JointType.FootLeft].Position.Z);
Console.WriteLine("#1: " + AngleBetweenTwoVectors(AnkleLeft - KneeLeft, AnkleLeft - FootLeft));
}
}
else
{
this.OnTrackingIdLost(null, null);
}
}
}
}
public double AngleBetweenTwoVectors(Vector3D vectorA, Vector3D vectorB)
{
double dotProduct = 0.0;
vectorA.Normalize();
vectorB.Normalize();
dotProduct = Vector3D.DotProduct(vectorA, vectorB);
return (double)Math.Acos(dotProduct) / Math.PI * 180;
}
TLDR 版本:根据您处理获取的 kinect 帧的方式,您需要在代码中识别正确的事件,即在帧中找到被跟踪的身体,在那里您可以查找不同身体的状态关节并计算角度。
此外,如果您愿意,可以将您的代码发送给我,我可以尝试为您连接,因为您的代码也会引起我的兴趣。