在Kinect SDK 2.0中计算和显示关节角度

时间:2015-04-02 17:06:34

标签: c# kinect-sdk

我目前正在开展一个需要跟踪关节角度(左膝盖)并在屏幕上实时显示的项目。我已经绘制了骨架,并设置了一个显示窗口,将骨架覆盖在人物的顶部。我正在用C#编程并使用Visual Studio 2013 Ultimate。

我在这里看到了这个链接kinect sdk 2.0 joint angles and tracking 但代码一直返回错误,因为底部的Results函数对我来说不存在,我无法弄清楚原因。此外,我无法弄清楚如何创建一个可以在屏幕上显示的变量,同时不断更新(如果不存在,它可以显示N / A或0)。

我还关注了回复此页面的人的链接Display the angles of each joint of the skeleton in kinect c# 但代码适用于SDK 1.X.

有没有人有关于如何解决我更新变量/定义结果的问题的示例代码或建议,以便我可以使用第一个示例中的代码?

1 个答案:

答案 0 :(得分:2)

虽然我没有看到你的代码或你是如何通过覆盖骨架实现人物跟踪的,但我建议你阅读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帧的方式,您需要在代码中识别正确的事件,在框架中找到跟踪的主体,在那里您可以查找不同身体的状态关节并计算角度。


此外,如果您希望您可以将代码发送给我,我可以尝试为您解决此问题,因为您的代码也会对我感兴趣。