Memorizza il file Kinect v2.0 Motion su BVH


298

Vorrei archiviare i dati di motion capture da Kinect 2 come file BVH. Ho trovato il codice che lo fa per Kinect 1 che può essere trovato qui . Ho esaminato il codice e ho trovato diverse cose che non riuscivo a capire. Ad esempio, nel codice citato ho cercato di capire cosa sia esattamente l' skeloggetto Skeleton , che si trova in diversi punti del codice. In caso contrario, sono disponibili applicazioni conosciute per realizzare le intenzioni?

EDIT: Ho provato a cambiare Skel Skeleton in Body skel che penso sia l'oggetto corrispondente per Kinect SDK 2.0. Tuttavia ho un errore quando provo a ottenere la posizione del corpo:

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

Ho ricevuto errori quando ho chiamato la funzione Position for the Body skel. Come posso recuperare la X, Y, Z dello scheletro in sdk 2.0 ?? Ho provato a cambiare le tre righe precedenti in:

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: Fondamentalmente sono riuscito a memorizzare il file a bvh dopo aver combinato bodyBasicsWPF e kinect2bvh. Tuttavia, sembra che lo scheletro che sto conservando non sia efficiente. Ci sono strani movimenti nei gomiti. Sto cercando di capire se devo cambiare qualcosa nel file kinectSkeletonBVH.cp . Più specificamente, quali sono i cambiamenti nell'orientamento dell'asse articolare per la versione kinect 2. Come posso cambiare la seguente riga: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; ho provato a cambiare quella linea con skel.JointOrientations[JointType.ShoulderCenter].Orientation. Ho ragione? Sto usando il seguente codice per aggiungere il giunto agli oggetti 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);

Non riesco a capire dove the axis for every Jointviene calcolato il codice .


9
Ho ignorato questo problema, tuttavia, se hai qualche soluzione, è bene pubblicarlo qui non solo per me, dal momento che ho notato che molte persone sono alla ricerca di memorizzazione dei movimenti nei file bhh.
Jose Ramon,

Sono in grado di memorizzare le informazioni Kinect v1 e v2 per un file txt. Questo file BVH è qualcosa che ho appena letto e sarà una funzionalità che aggiungerò al nostro software di acquisizione. Se sei interessato ai file * .txt, fammelo sapere. Non ho ancora una soluzione BVH adeguata.
16per9


1
Ho un modo per scrivere correttamente i flussi Kinect v1 e Kinect v2 in txt. Forse se lo usi, puoi ricontrollare i file del tuo bvh per lo stesso esperimento. Controlla la mia biografia per ulteriori informazioni.
16per9

1
@ Khaled.K Se il link che hai pubblicato risponde a questa domanda, ti dispiacerebbe trasformarlo in una risposta a questa domanda (per questa meta domanda )
Matt Thomas

Risposte:


2

Il codice utilizzato per Kinect 1.0 per ottenere un file BVH utilizza le informazioni sulle articolazioni per creare vettori ossei leggendo lo scheletro .

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

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

Ad eccezione di Kinect 2.0 , la classe Skeleton è stata sostituita dalla classe Body , quindi è necessario cambiarla per gestire un Body e ottenere le articolazioni seguendo i passaggi indicati di seguito.

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

Abbiamo anche aggiunto un elenco di corpi, in cui verranno salvati tutti i dati relativi al corpo / scheletro. Se hai sviluppato per Kinect versione 1, noti che la classe Skeleton è stata sostituita dalla classe Body. Ricorda MultiSourceFrameReader? Questa classe ci dà accesso a tutti i flussi, incluso il flusso corporeo! Dobbiamo semplicemente far sapere al sensore che abbiamo bisogno della funzionalità di tracciamento del corpo aggiungendo un parametro aggiuntivo durante l'inizializzazione del lettore:

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

_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;

Il metodo Reader_MultiSourceFrameArrived verrà chiamato ogni volta che è disponibile un nuovo frame. Specifichiamo cosa accadrà in termini di dati corporei:

  1. Ottieni un riferimento al telaio del corpo
  2. Controlla se il telaio del corpo è nullo - questo è cruciale
  3. Inizializza l'elenco _bodies
  4. Chiamare il metodo GetAndRefreshBodyData, in modo da copiare i dati del corpo nell'elenco
  5. Scorri l'elenco dei corpi e fai cose fantastiche!

Ricorda sempre di controllare i valori null. Kinect ti fornisce circa 30 frame al secondo: qualsiasi cosa potrebbe essere nulla o mancante! Ecco il codice finora:

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

Questo è! Ora abbiamo accesso ai corpi identificati da Kinect. Il prossimo passo è visualizzare le informazioni sullo scheletro sullo schermo. Ogni corpo è composto da 25 articolazioni. Il sensore ci fornisce la posizione (X, Y, Z) e le informazioni di rotazione per ognuna di esse. Inoltre, Kinect ci consente di sapere se le articolazioni sono tracciate, ipotizzate o meno. È buona norma verificare se un corpo viene rintracciato prima di eseguire qualsiasi funzione critica.

Il seguente codice illustra come possiamo accedere alle diverse articolazioni del corpo:

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

Fonte: Blog Vangos Pterneas - KINECT FOR WINDOWS VERSIONE 2: BODY TRACKING

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.