Stocker le mouvement v2.0 de Kinect dans un fichier BVH

298

Je voudrais stocker les données de capture de mouvement de Kinect 2 sous forme de fichier BVH. J'ai trouvé le code qui le fait pour Kinect 1 qui peut être trouvé ici . J'ai parcouru le code et trouvé plusieurs choses que je ne pouvais pas comprendre. Par exemple, dans le code mentionné, j'ai essayé de comprendre ce qu'est exactement l' skelobjet Skeleton , trouvé à plusieurs endroits dans le code. Si ce n'est pas le cas, existe-t-il une application connue disponible pour atteindre l'objectif recherché?

EDIT: J'ai essayé de changer Skeleton skel en Body skel qui je pense est l'objet correspondant pour kinect SDK 2.0. Cependant, j'ai une erreur lorsque j'essaie d'obtenir la position du corps:

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

J'ai eu des erreurs lors de l'appel de la fonction Position pour le skel Body. Comment puis-je récupérer les X, Y, Z du squelette dans sdk 2.0 ?? J'ai essayé de changer les trois lignes ci-dessus en:

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: Fondamentalement, j'ai réussi à stocker le fichier bvh après avoir combiné bodyBasicsWPF et kinect2bvh. Cependant, il semble que le squelette que je stocke n'est pas efficace. Il y a d'étranges mouvements dans les coudes. J'essaie de comprendre si je dois changer quelque chose dans le fichier kinectSkeletonBVH.cp . Plus précisément, quels sont les changements d'orientation de l'axe des articulations pour la version kinect 2. Comment puis-je changer la ligne suivante: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; J'ai essayé de changer cette ligne avec skel.JointOrientations[JointType.ShoulderCenter].Orientation. Ai-je raison? J'utilise le code suivant pour ajouter le joint aux objets 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);

Je ne comprends pas où le code the axis for every Jointest calculé.

Jose Ramon
la source
9
J'ai cependant ignoré ce problème. Si vous avez une solution, il est bon de la publier ici, pas seulement pour moi, car j'ai remarqué que beaucoup de gens recherchaient le stockage des mouvements dans des fichiers bvh.
Jose Ramon
Je peux stocker les informations Kinect v1 et v2 pour un fichier txt. Ce fichier BVH est quelque chose que je viens de lire et ce sera une fonctionnalité que j'ajouterai à notre logiciel d'acquisition. Si vous êtes intéressé par les fichiers * .txt, faites le moi savoir. Je n'ai pas encore de solution BVH appropriée.
16per9
2
check: pterneas.com/2014/03/13/…
Khaled.K
1
J'ai un moyen d'écrire correctement les flux Kinect v1 et Kinect v2 dans txt. Peut-être que si vous l'utilisez, vous pouvez vérifier ensuite les fichiers de votre bvh pour la même expérience. Consultez ma bio pour plus d'informations.
16per9
1
@ Khaled.K Si le lien que vous avez publié répond à cela, cela vous dérangerait-il d'en faire une réponse à cette question (par cette méta-question )
Matt Thomas

Réponses:

2

Le code que vous avez utilisé pour Kinect 1.0 pour obtenir un fichier BVH utilise les informations sur les articulations pour créer des vecteurs osseux en lisant le squelette .

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

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

Sauf dans Kinect 2.0 , la classe Skeleton a été remplacée par la classe Body , vous devez donc la modifier pour gérer un corps à la place et obtenir les articulations en suivant les étapes citées ci-dessous.

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

Nous avons également ajouté une liste de corps, où toutes les données liées au corps / squelette seront enregistrées. Si vous avez développé pour Kinect version 1, vous remarquez que la classe Skeleton a été remplacée par la classe Body. Rappelez-vous le MultiSourceFrameReader? Cette classe nous donne accès à tous les flux, y compris le flux de corps! Nous devons simplement faire savoir au capteur que nous avons besoin d'une fonctionnalité de suivi du corps en ajoutant un paramètre supplémentaire lors de l'initialisation du lecteur:

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

_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;

La méthode Reader_MultiSourceFrameArrived sera appelée chaque fois qu'une nouvelle trame est disponible. Précisons ce qui se passera en termes de données corporelles:

  1. Obtenez une référence au châssis
  2. Vérifiez si le cadre du corps est nul - c'est crucial
  3. Initialiser la liste _bodies
  4. Appelez la méthode GetAndRefreshBodyData, afin de copier les données du corps dans la liste
  5. Parcourez la liste des corps et faites des trucs géniaux!

N'oubliez pas de vérifier les valeurs nulles. Kinect vous fournit environ 30 images par seconde - tout peut être nul ou manquant! Voici le code jusqu'à présent:

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

Ça y est ...! Nous avons maintenant accès aux corps identifiés par Kinect. L'étape suivante consiste à afficher les informations du squelette à l'écran. Chaque corps se compose de 25 articulations. Le capteur nous fournit la position (X, Y, Z) et les informations de rotation pour chacun d'eux. De plus, Kinect nous permet de savoir si les articulations sont suivies, supposées ou non suivies. C'est une bonne pratique de vérifier si un corps est suivi avant d'exécuter des fonctions critiques.

Le code suivant illustre comment nous pouvons accéder aux différentes articulations du corps:

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

Source: Blog Vangos Pterneas - KINECT POUR WINDOWS VERSION 2: SUIVI DU CORPS

Khaled.K
la source