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.