Kinect's v2.0 Motion'ı BVH Dosyasına Kaydetme


298

Kinect 2'den hareket yakalama verilerini BVH dosyası olarak saklamak istiyorum. Burada bulunan Kinect 1 için bunu yapan bir kod buldum . Koddan geçtim ve anlayamadığım birkaç şey buldum. Örneğin, bahsi geçen kodda skel, kodun çeşitli yerlerinde bulunan Skeleton nesnesinin tam olarak ne olduğunu anlamaya çalıştım . Değilse, amaçlananı gerçekleştirmek için bilinen herhangi bir uygulama var mı?

DÜZENLEME: Kinect SDK 2.0 için uygun nesne olduğunu düşündüğüm İskelet iskeletini Vücut iskeletine değiştirmeye çalıştım. Ancak vücudun pozisyonunu almaya çalıştığımda bir hata var:

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

Vücut iskeleti için Pozisyon fonksiyonunu çağırırken hatalar aldım. SDK 2.0 iskeletin X, Y, Z nasıl alabilirim? Yukarıdaki üç satırı şu şekilde değiştirmeye çalıştım:

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: Temelde bodyBasicsWPF ve kinect2bvh birleştirdikten sonra bvh dosyasını depolamayı başardı. Ancak, depoladığım iskeletin etkili olmadığı anlaşılıyor. Dirseklerde garip hareketler var. KinectSkeletonBVH.cp dosyasındaki bir şeyi değiştirmem gerekip gerekmediğini anlamaya çalışıyorum . Daha spesifik olarak, kinect 2 versiyonu için eklem ekseni yönündeki değişiklikler nelerdir. Aşağıdaki satırı nasıl değiştirebilirim: skel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; Bu satırı ile değiştirmeye çalıştım skel.JointOrientations[JointType.ShoulderCenter].Orientation. Haklı mıyım? BVHBone nesnelerine eklem eklemek için aşağıdaki kodu kullanıyorum:

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

Kodun nerede the axis for every Jointhesaplandığını anlayamıyorum .


9
Bu sorunu atladım, ancak herhangi bir çözümünüz varsa, sadece benim için değil, burada yayınlamak iyidir, çünkü birçok insanın bvh dosyalarında hareketleri saklamak için arama yaptığını fark ettim.
Jose Ramon

Bir txt dosyası için Kinect v1 ve v2 bilgilerini saklayabiliyorum. Bu BVH dosyası yeni okuduğum bir şey ve edinme yazılımımıza ekleyeceğim bir özellik olacak. * .Txt dosyaları ile ilgileniyorsanız bana bildirin. Henüz uygun bir BVH çözümüm yok.
16per9


1
Txt içine Kinect v1 ve Kinect v2 akışları düzgün yazmak için bir yol var. Belki kullanırsanız, bvh'nizin dosyalarını aynı deneme için iki kez kontrol edebilirsiniz. Daha fazla bilgi için biyografimi kontrol et.
16per9

1
@ Khaled.K Gönderdiğiniz bağlantı buna cevap verirse, bunu bu soruya bir cevap haline getirmeyi düşünür müsünüz ( bu meta soru başına )
Matt Thomas

Yanıtlar:


2

Kinect 1.0 için bir BVH dosyası elde etmek için kullandığınız kod , İskelet'i okuyarak kemik vektörleri oluşturmak için eklem bilgilerini kullanır .

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

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

Kinect 2.0 dışında , Skeleton sınıfının yerini Body sınıfı almıştır, bu nedenle bunun yerine bir Body ile başa çıkmak için onu değiştirmeniz ve aşağıda belirtilen adımları izleyerek eklemleri almanız gerekir.

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

Vücut / iskeletle ilgili tüm verilerin kaydedileceği bir gövde listesi de ekledik. Kinect sürüm 1 için geliştirdiyseniz, Skeleton sınıfının Body sınıfıyla değiştirildiğini fark edersiniz. MultiSourceFrameReader'ı hatırlıyor musunuz? Bu sınıf, vücut akışı da dahil olmak üzere her akışta bize erişim sağlıyor! Okuyucuyu başlatırken ek bir parametre ekleyerek sensöre vücut izleme işlevselliğine ihtiyacımız olduğunu bildirmemiz yeterlidir:

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

_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;

Reader_MultiSourceFrameArrived yöntemi, yeni bir çerçeve kullanılabilir olduğunda çağrılır. Vücut verileri açısından ne olacağını belirleyelim:

  1. Gövde çerçevesine referans alın
  2. Gövde çerçevesinin boş olup olmadığını kontrol edin - bu çok önemlidir
  3. _Bodies listesini başlat
  4. Gövde verilerini listeye kopyalamak için GetAndRefreshBodyData yöntemini çağırın
  5. Cesetler listesinde dolaşın ve harika şeyler yapın!

Her zaman null değerleri kontrol etmeyi unutmayın. Kinect saniyede yaklaşık 30 kare sağlar - her şey boş veya eksik olabilir! İşte şimdiye kadar kod:

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

Budur! Artık Kinect'in tanımladığı organlara erişimimiz var. Sonraki adım, iskelet bilgilerinin ekranda görüntülenmesidir. Her vücut 25 eklemden oluşur. Sensör bize her biri için konum (X, Y, Z) ve dönüş bilgilerini sağlar. Dahası, Kinect eklemlerin izlendiğini, varsayıldığını veya izlenmediğini bize bildirir. Herhangi bir kritik işlevi yerine getirmeden önce bir vücudun izlenip izlenmediğini kontrol etmek iyi bir uygulamadır.

Aşağıdaki kod, farklı vücut eklemlerine nasıl erişebileceğimizi göstermektedir:

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

Kaynak: Vangos Pterneas Blog - WINDOWS VERSİYONU İÇİN KINECT 2: VÜCUT TAKİP

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.