繁体   English   中英

将Kinect的v2.0 Motion存储到BVH文件中

[英]Store Kinect's v2.0 Motion to BVH File

我想将Kinect 2中的动作捕捉数据存储为BVH文件。 我找到了Kinect 1的代码,可以在这里找到。 我查看了代码,发现了一些我无法理解的内容。 例如,在上面提到的代码中,我试图理解在代码中的几个地方找到的Skeleton skel对象到底是什么。 如果没有,是否有任何已知的应用程序可用于完成预期的?

编辑:我试图将Skeleton skel更改为Body skel,我认为它是kinect SDK 2.0的对应对象。 但是当我试图获得身体的位置时,我遇到了错误:

tempMotionVektor[0] = -Math.Round( skel.Position.X * 100,2);
tempMotionVektor[1] = Math.Round( skel.Position.Y * 100,2) + 120;
tempMotionVektor[2] = 300 - Math.Round( skel.Position.Z * 100,2);

调用Body skel的函数Position时,我遇到了错误。 如何在sdk 2.0中检索骨架的X,Y,Z? 我试图将以上三行更改为:

tempMotionVektor[0] = -Math.Round(skel.Joints[0].Position.X * 100, 2);
tempMotionVektor[1] = Math.Round(skel.Joints[0].Position.Y * 100, 2) + 120;
tempMotionVektor[2] = 300 - Math.Round(skel.Joints[0].Position.Z * 100, 2);

编辑:基本上我设法在bodyBasicsWPF和kinect2bvh组合后存储一个bvh文件。 然而,似乎我存储的骨架效率不高。 肘部有奇怪的动作。 我想知道我是否必须更改文件kinectSkeletonBVH.cp中的内容 更具体地说,kinect 2版本的关节轴方向的变化是什么。 如何更改以下行: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; 我尝试用skel.JointOrientations[JointType.ShoulderCenter].Orientation更改该行skel.JointOrientations[JointType.ShoulderCenter].Orientation 我对吗? 我使用以下代码将关节添加到BVHBone对象:

BVHBone hipCenter = new BVHBone(null, JointType.SpineBase.ToString(), 6, TransAxis.None, true);
BVHBone hipCenter2 = new BVHBone(hipCenter, "HipCenter2", 3, TransAxis.Y, false);
BVHBone spine = new BVHBone(hipCenter2, JointType.SpineMid.ToString(), 3, TransAxis.Y, true);
BVHBone shoulderCenter = new BVHBone(spine, JointType.SpineShoulder.ToString(), 3, TransAxis.Y, true);

BVHBone collarLeft = new BVHBone(shoulderCenter, "CollarLeft", 3, TransAxis.X, false);
BVHBone shoulderLeft = new BVHBone(collarLeft, JointType.ShoulderLeft.ToString(), 3, TransAxis.X, true);
BVHBone elbowLeft = new BVHBone(shoulderLeft, JointType.ElbowLeft.ToString(), 3, TransAxis.X, true);
BVHBone wristLeft = new BVHBone(elbowLeft, JointType.WristLeft.ToString(), 3, TransAxis.X, true);
BVHBone handLeft = new BVHBone(wristLeft, JointType.HandLeft.ToString(), 0, TransAxis.X, true);

BVHBone neck = new BVHBone(shoulderCenter, "Neck", 3, TransAxis.Y, false);
BVHBone head = new BVHBone(neck, JointType.Head.ToString(), 3, TransAxis.Y, true);
BVHBone headtop = new BVHBone(head, "Headtop", 0, TransAxis.None, false);

我无法理解代码内部the axis for every Joint计算方法。

您用于Kinect 1.0获取BVH文件的代码使用关节信息通过读取Skeleton来构建骨骼向量。

public static double[] getBoneVectorOutofJointPosition(BVHBone bvhBone, Skeleton skel)
{
    double[] boneVector = new double[3] { 0, 0, 0 };
    double[] boneVectorParent = new double[3] { 0, 0, 0 };
    string boneName = bvhBone.Name;

    JointType Joint;
    if (bvhBone.Root == true)
    {
        boneVector = new double[3] { 0, 0, 0 };
    }
    else
    {
        if (bvhBone.IsKinectJoint == true)
        {
            Joint = KinectSkeletonBVH.String2JointType(boneName);

            boneVector[0] = skel.Joints[Joint].Position.X;
            boneVector[1] = skel.Joints[Joint].Position.Y;
            boneVector[2] = skel.Joints[Joint].Position.Z;
..

资料来源: NguyênLêĐặng - Kinect2BVH.V2

除了在Kinect 2.0中Skeleton类已被Body类替换,因此您需要更改它以处理Body ,并按照下面引用的步骤获取关节。

 // Kinect namespace using Microsoft.Kinect; // ... // Kinect sensor and Kinect stream reader objects KinectSensor _sensor; MultiSourceFrameReader _reader; IList<Body> _bodies; // Kinect sensor initialization _sensor = KinectSensor.GetDefault(); if (_sensor != null) { _sensor.Open(); } 

我们还添加了一个实体列表,其中将保存所有与身体/骨架相关的数据。 如果您已经为Kinect版本1开发,您会注意到Skeleton类已被Body类替换。 还记得MultiSourceFrameReader吗? 这个课程让我们可以访问每一个流,包括正文流! 我们只需要在初始化阅读器时通过添加附加参数让传感器知道我们需要身体跟踪功能:

 _reader = _sensor.OpenMultiSourceFrameReader(FrameSourceTypes.Color | FrameSourceTypes.Depth | FrameSourceTypes.Infrared | FrameSourceTypes.Body); _reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived; 

只要有新帧可用,就会调用Reader_MultiSourceFrameArrived方法。 让我们指定一下身体数据会发生什么:

  1. 获取身体框架的参考
  2. 检查体框是否为空 - 这是至关重要的
  3. 初始化_bodies列表
  4. 调用GetAndRefreshBodyData方法,以便将正文数据复制到列表中
  5. 循环遍历尸体列表并做一些很棒的东西!

始终记得检查空值。 Kinect为您提供大约每秒30帧的速度 - 任何东西都可以为空或丢失! 这是迄今为止的代码:

 void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { var reference = e.FrameReference.AcquireFrame(); // Color // ... // Depth // ... // Infrared // ... // Body using (var frame = reference.BodyFrameReference.AcquireFrame()) { if (frame != null) { _bodies = new Body[frame.BodyFrameSource.BodyCount]; frame.GetAndRefreshBodyData(_bodies); foreach (var body in _bodies) { if (body != null) { // Do something with the body... } } } } } 

就是这个! 我们现在可以访问Kinect标识的机构。 下一步是在屏幕上显示骨架信息。 每个身体由25个关节组成。 传感器为我们提供每个位置(X,Y,Z)和旋转信息。 此外,Kinect让我们知道关节是否被跟踪,是否被追踪或被跟踪。 在执行任何关键功能之前检查是否跟踪了主体是一个好习惯。

以下代码说明了我们如何访问不同的身体关节:

 if (body != null) { if (body.IsTracked) { Joint head = body.Joints[JointType.Head]; float x = head.Position.X; float y = head.Position.Y; float z = head.Position.Z; // Draw the joints... } } 

资料来源: Vangos Pterneas博客 - WINDOWS版本2的KINECT:BODY TRACKING

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM