簡體   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