我想将Kinect 2中的动作捕捉数据存储为BVH文件。我找到了Kinect 1的代码,可以找到here。我查看了代码,发现了一些我无法理解的内容。
例如,在上面提到的代码中,我试图理解在代码中的几个地方找到的Skeleton skel
对象究竟是什么。如果没有,是否有任何已知的应用程序可用于实现预期的?
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
更改该行。我对吗?我使用以下代码将关节添加到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
内部的计算位置。
答案 0 :(得分:2)
您用于 Kinect 1.0 以获取 BVH 文件的代码使用关节信息通过阅读 Skeleton 来构建骨骼矢量。 / p>
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 外, Skeleton 类已被 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;
每当a调用Reader_MultiSourceFrameArrived方法 新框架可用。让我们来说明将会发生什么 身体数据:
- 获取对框架的引用
- 检查正文框架是否为空 - 这是至关重要的
- 初始化_bodies列表
- 调用GetAndRefreshBodyData方法,以便将正文数据复制到列表中
- 遍历尸体列表并做一些很棒的东西!
醇>始终记得检查空值。 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 让我们知道关节是否被跟踪,是否被假定 跟踪。检查身体是否被跟踪是一个好习惯 在执行任何关键功能之前。
以下代码说明了我们如何访问不同的主体 缝:
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 Blog - KINECT FOR WINDOWS VERSION 2: BODY TRACKING