存储Kinect's v2.0运动到BVH文件

我想把Kinect 2的动作捕捉数据存储为BVH文件。我找到了Kinect 1的代码,可以找到在这里。我检查了代码,发现了一些我不能理解的东西。 例如,在上述代码中,我试图理解在代码中几个地方发现的Skeleton skel对象究竟是什么。如果不是,是否有任何已知的应用程序可以完成预期的目标?< / p >

编辑:我试图改变骷髅的skel身体的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的函数位置时出错。我怎么能检索X, Y, Z的骨架在sdk 2.0??我试着把上面的三行改为:

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

编辑:基本上我设法存储一个bvh文件后结合bodyBasicsWPF和kinect2bvh。然而,我存储的骨架似乎效率不高。肘部有奇怪的动作。我正在尝试了解我是否必须更改文件kinectSkeletonBVH.cp中的某些内容。更具体地说,kinect 2版本的关节轴方向有哪些变化。我试图用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是在哪里计算的。

10283 次浏览

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

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中,骨架类已经被身体类所取代,所以你需要改变它来处理身体,并按照下面引用的步骤获取关节。

// 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类所取代。 还记得multisourceframeread吗?这个类让我们访问 每一条溪流,包括身体的溪流!我们只需要让 传感器知道我们需要身体跟踪功能 初始化读取器时的附加参数:

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


_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;

Reader_MultiSourceFrameArrived方法将被调用 新框架可用。我们来详细说明会发生什么 身体数据:< / p >

  1. 得到一个身体框架的参考
  2. 检查主体帧是否为空-这是至关重要的
  3. 初始化_bodies列表
  4. 调用GetAndRefreshBodyData方法,以便将body数据复制到列表中
  5. 循环遍历尸体列表,做很棒的事情!
总是记得检查空值。Kinect为你提供 大约每秒30帧-任何东西都可以为null或 失踪!下面是目前为止的代码:

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 让我们知道关节是否被追踪,假设是否 跟踪。检查尸体是否被跟踪是一个很好的做法

.在执行任何关键功能之前 下面的代码说明了我们如何访问不同的主体 关节:< / p >
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博客- KINECT为WINDOWS版本2:身体跟踪