首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将Kinect的v2.0运动存储到BVH文件

将Kinect的v2.0运动存储到BVH文件
EN

Stack Overflow用户
提问于 2015-05-26 16:42:00
回答 1查看 10.1K关注 0票数 297

我想将Kinect 2中的动作捕捉数据存储为BVH文件。我找到了为kinect1做这件事的代码,可以找到here。我仔细阅读了代码,发现了一些我不能理解的东西。例如,在前面提到的代码中,我试图理解在代码中的几个地方找到的Skeleton skel对象到底是什么。如果没有,是否有任何已知的应用程序可用于实现预期目标?

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

代码语言:javascript
复制
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);

代码语言:javascript
复制
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);

手肘有奇怪的动作。我说的对吗?

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-25 17:40:28

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

代码语言:javascript
复制
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ên Lê Đặng - Kinect2BVH.V2

除了在Kinect 2.0中,骨架类已被Body类替换,因此您需要将其更改为处理Body,并通过以下引用的步骤获取关节。

//使用Microsoft.Kinect的Kinect命名空间;// ... // Kinect传感器和Kinect流阅读器对象KinectSensor _sensor;MultiSourceFrameReader _reader;IList _bodies;// Kinect传感器初始化_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方法。让我们指定在正文数据方面会发生什么:

获取对body frame的引用并检查body frame是否为空- this is crucial

  • Initialize _bodies
  1. 调用GetAndRefreshBodyData方法,以便通过body列表将body数据复制到list
  2. 循环中,并做一些很棒的事情!

始终记住检查是否有空值。Kinect为您提供大约每秒30帧-任何内容都可能为空或丢失!以下是到目前为止的代码:

void引用(对象发送者,MultiSourceFrameArrivedEventArgs e) { var Reader_MultiSourceFrameArrived= e.FrameReference.AcquireFrame();//颜色// ... //深度// ... //红外// ... //身体使用(var Bodyframe.BodyFrameSource.BodyCount= reference.BodyFrameReference.AcquireFrame()) { if (frame != null) { _bodies =新帧;frame.GetAndRefreshBodyData(_bodies);foreach (_bodies中的var body ){ if (body != null) { //对body执行某些操作...}

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

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

if (body != null) { if (body.IsTracked) {关节头部= body.JointsJointType.Head;float x= head.Position.X;float y= head.Position.Y;float z= head.Position.Z;//绘制关节...}}

来源:Vangos Pterneas Blog - KINECT FOR WINDOWS VERSION 2: BODY TRACKING

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30453656

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档