2015-05-26 13 views
297

Ich möchte die Motion Capture-Daten von Kinect 2 als BVH-Datei speichern. Ich habe Code gefunden, der dies für Kinect 1 tut, den man finden kann here. Ich ging durch den Code und fand einige Dinge, die ich nicht verstehen konnte. Zum Beispiel, in dem erwähnten Code habe ich versucht zu verstehen, was genau das Skelett skel Objekt, das an mehreren Stellen im Code gefunden wird, tatsächlich ist. Wenn nicht, gibt es eine bekannte Anwendung, um das beabsichtigte zu erreichen?Speichern Kinect v2.0 Motion zu BVH Datei

EDIT: Ich habe versucht, Skelet Skel zu Body Skel zu ändern, die ich denke, ist das entsprechende Objekt für kinect SDK 2.0. Allerdings habe ich einen Fehler bekam, wenn ich versuche, die Position des Körpers zu erhalten:

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

Ich habe Fehler bekommen, wenn die Funktion Position für den Körper skel aufrufen. Wie kann ich die X, Y, Z des Skeletts in SDK 2.0 abrufen? Ich habe versucht, die oben genannten drei Linien zu ändern:

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: Im Grunde ich das ein bvh-Datei nach bodyBasicsWPF und kinect2bvh Kombination speichern verwaltet. Es scheint jedoch, dass das Skelett, das ich speichere, nicht effizient ist. Es sind seltsame Bewegungen in den Ellbogen. Ich versuche zu verstehen, ob ich etwas in der Datei kinectSkeletonBVH.cp ändern muss. Genauer gesagt, was sind die Änderungen in der Ausrichtung der Gelenkachse für die Version kinect 2? Wie kann ich die folgende Zeile ändern: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; Ich habe versucht, diese Zeile mit skel.JointOrientations[JointType.ShoulderCenter].Orientation zu ändern. Habe ich recht? Ich verwende den folgenden Code, um das Gelenk zu BVHBone Objekte hinzuzufügen:

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

Ich kann nicht verstehen, wo innerhalb der Code the axis for every Joint berechnet wird.

+9

ich jedoch dieses Problem übersprungen Wenn Sie eine Lösung haben, ist es gut, sie hier posten nicht nur für mich, da ich eine Menge Leute bemerkte, die nach Bewegungen in bvh-Dateien suchten. –

+0

Ich bin in der Lage, die Kinect v1 und v2 Informationen für eine TXT-Datei zu speichern. Diese BVH-Datei ist etwas, das ich gerade gelesen habe und es wird ein Feature sein, das ich zu unserer Akquisitionssoftware hinzufügen werde. Wenn Sie an den * .txt-Dateien interessiert sind, lassen Sie es mich wissen. Ich habe noch keine richtige BVH-Lösung. – 16per9

+2

überprüfen: http://pterneas.com/2014/03/13/kinect-for-windows-version-2-body-tracking –

Antwort

1

Der Code, den Sie für verwendet Kinect 1.0 eine BVH Datei, um die Gelenke Informationen Knochen Vektoren verwenden zu erhalten aufzubauen, indem die Skeleton lesen.

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

Quelle: Nguyên Lê Đặng - Kinect2BVH.V2

Außer in Kinect 2.0, Skeleton Klasse wird von der Körper Klasse ersetzt, so dass Sie es ändern müssen stattdessen mit einem Körper zu behandeln, und erhalte die Gelenke, indem du die folgenden Schritte befolgst.

// 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(); 
} 

Außerdem haben wir eine Liste von Einrichtungen, in denen alle des Körpers/Skelett im Zusammenhang Daten werden gespeichert. Wenn Sie für Kinect Version 1 entwickelt haben, beachten Sie , dass die Skeleton-Klasse durch die Body-Klasse ersetzt wurde. Erinnerst du dich an den MultiSourceFrameReader? Diese Klasse gibt uns Zugriff auf jeden Stream, einschließlich der Körper-Stream!Wir müssen einfach die Sensor wissen lassen, dass wir Körper-Tracking-Funktionalität müssen durch Hinzufügen eines zusätzlichen Parameter, wenn der Leser Initialisierung:

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

_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived; 

Die Reader_MultiSourceFrameArrived Methode aufgerufen wird, sobald ein neuer Rahmen zur Verfügung steht. Lassen Sie uns geben, was im Hinblick auf die Körperdaten passieren wird:

  1. Erhalten Sie einen Verweis auf den Körperrahmen
  2. Überprüfen Sie, ob der Körperrahmen ist null - das ist entscheidend
  3. Initialisieren der _bodies Liste
  4. Rufen Sie die GetAndRefreshBodyData-Methode auf, um die Körperdaten in die Liste zu kopieren
  5. Gehen Sie durch die Liste der Körper und machen Sie tolle Sachen!

Denken Sie immer daran, nach Nullwerten zu suchen. Kinect bietet Ihnen ungefähr 30 Bilder pro Sekunde - alles könnte null sein oder fehlen! Hier ist der Code so weit:

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

Das ist es! Wir haben jetzt Zugriff auf die Stellen, die Kinect identifiziert. Weiter Schritt zeigt die Skeleton-Informationen auf dem Bildschirm an. Jeder Körper besteht aus 25 Gelenken. Der Sensor liefert uns die Position (X, Y, Z) und die Rotationsinformationen für jede von ihnen. Darüber hinaus informiert uns Kinect , ob die Verbindungen verfolgt, hypothesiert oder nicht verfolgt werden. Es empfiehlt sich, vor der Durchführung kritischer Funktionen zu prüfen, ob ein Körper verfolgt wird.

Der folgende Code zeigt, wie wir die verschiedenen Körper Gelenke zugreifen:

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

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