简体   繁体   English

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

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

I would like to store the motion capture data from Kinect 2 as a BVH file. 我想将Kinect 2中的动作捕捉数据存储为BVH文件。 I found code which does so for Kinect 1 which can be found here . 我找到了Kinect 1的代码,可以在这里找到。 I went through the code and found several things that I was not able to understand. 我查看了代码,发现了一些我无法理解的内容。 For example, in the mentioned code I've tried to understand what exactly the Skeleton skel object, found in several places in the code, actually is. 例如,在上面提到的代码中,我试图理解在代码中的几个地方找到的Skeleton skel对象到底是什么。 If not, are there any known application available to accomplish the intended? 如果没有,是否有任何已知的应用程序可用于完成预期的?

EDIT: I tried to change Skeleton skel to Body skel which I think is the correspondant object for kinect SDK 2.0. 编辑:我试图将Skeleton skel更改为Body skel,我认为它是kinect SDK 2.0的对应对象。 However I've got an error when I try to get the position of the body: 但是当我试图获得身体的位置时,我遇到了错误:

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);

I've gotten errors when calling the function Position for the Body skel. 调用Body skel的函数Position时,我遇到了错误。 How can I retrieve the X, Y, Z of the skeleton in sdk 2.0?? 如何在sdk 2.0中检索骨架的X,Y,Z? I tried to change the above three lines to: 我试图将以上三行更改为:

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);

EDIT: Basically I managed to store the a bvh file after combining bodyBasicsWPF and kinect2bvh. 编辑:基本上我设法在bodyBasicsWPF和kinect2bvh组合后存储一个bvh文件。 However, it seems that the skeleton I am storing is not efficient. 然而,似乎我存储的骨架效率不高。 There are strange movements in the elbows. 肘部有奇怪的动作。 I am trying to understand if I have to change something in the file kinectSkeletonBVH.cp . 我想知道我是否必须更改文件kinectSkeletonBVH.cp中的内容 More specifically, what are the changes in the joint axis orientation for the kinect 2 version. 更具体地说,kinect 2版本的关节轴方向的变化是什么。 How can I change the following line: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; 如何更改以下行: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; I tried to change that line with skel.JointOrientations[JointType.ShoulderCenter].Orientation . 我尝试用skel.JointOrientations[JointType.ShoulderCenter].Orientation更改该行skel.JointOrientations[JointType.ShoulderCenter].Orientation Am I right? 我对吗? I am using the following code to add the joint to BVHBone objects: 我使用以下代码将关节添加到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);

I can't understand where inside the code the axis for every Joint is calculated. 我无法理解代码内部the axis for every Joint计算方法。

The code you used for Kinect 1.0 to obtain a BVH file use the joints information to build bone vectors by reading the Skeleton . 您用于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;
..

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

Except in Kinect 2.0 , Skeleton class has been replaced by the Body class, so you need to change it to deal with a Body instead, and obtain the joints by following the steps quoted below. 除了在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(); } 

We also added a list of bodies, where all of the body/skeleton related data will be saved. 我们还添加了一个实体列表,其中将保存所有与身体/骨架相关的数据。 If you have developed for Kinect version 1, you notice that the Skeleton class has been replaced by the Body class. 如果您已经为Kinect版本1开发,您会注意到Skeleton类已被Body类替换。 Remember the MultiSourceFrameReader? 还记得MultiSourceFrameReader吗? This class gives us access on every stream, including the body stream! 这个课程让我们可以访问每一个流,包括正文流! We simply need to let the sensor know that we need body tracking functionality by adding an additional parameter when initializing the reader: 我们只需要在初始化阅读器时通过添加附加参数让传感器知道我们需要身体跟踪功能:

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

The Reader_MultiSourceFrameArrived method will be called whenever a new frame is available. 只要有新帧可用,就会调用Reader_MultiSourceFrameArrived方法。 Let's specify what will happen in terms of the body data: 让我们指定一下身体数据会发生什么:

  1. Get a reference to the body frame 获取身体框架的参考
  2. Check whether the body frame is null – this is crucial 检查体框是否为空 - 这是至关重要的
  3. Initialize the _bodies list 初始化_bodies列表
  4. Call the GetAndRefreshBodyData method, so as to copy the body data into the list 调用GetAndRefreshBodyData方法,以便将正文数据复制到列表中
  5. Loop through the list of bodies and do awesome stuff! 循环遍历尸体列表并做一些很棒的东西!

Always remember to check for null values. 始终记得检查空值。 Kinect provides you with approximately 30 frames per second – anything could be null or missing! Kinect为您提供大约每秒30帧的速度 - 任何东西都可以为空或丢失! Here is the code so far: 这是迄今为止的代码:

 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... } } } } } 

This is it! 就是这个! We now have access to the bodies Kinect identifies. 我们现在可以访问Kinect标识的机构。 Next step is to display the skeleton information on-screen. 下一步是在屏幕上显示骨架信息。 Each body consists of 25 joints. 每个身体由25个关节组成。 The sensor provides us with the position (X, Y, Z) and the rotation information for each one of them. 传感器为我们提供每个位置(X,Y,Z)和旋转信息。 Moreover, Kinect lets us know whether the joints are tracked, hypothsized or not tracked. 此外,Kinect让我们知道关节是否被跟踪,是否被追踪或被跟踪。 It's a good practice to check whether a body is tracked before performing any critical functions. 在执行任何关键功能之前检查是否跟踪了主体是一个好习惯。

The following code illustrates how we can access the different body joints: 以下代码说明了我们如何访问不同的身体关节:

 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... } } 

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

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

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