จัดเก็บไฟล์ v2.0 Motion to BVH ของ Kinect


298

ฉันต้องการจัดเก็บข้อมูลการจับการเคลื่อนไหวจาก Kinect 2 เป็นไฟล์ BVH ผมพบว่ารหัสที่ไม่ดังนั้นสำหรับ Kinect 1 ซึ่งสามารถพบได้ที่นี่ ฉันผ่านรหัสและพบหลายสิ่งที่ฉันไม่สามารถเข้าใจได้ ตัวอย่างเช่นในรหัสที่กล่าวถึงฉันพยายามที่จะเข้าใจว่าskelวัตถุSkeleton ที่พบในหลาย ๆ ที่ในรหัสจริงคืออะไร หากไม่มีมีแอปพลิเคชันใดที่รู้จักกันเพื่อให้บรรลุตามวัตถุประสงค์

แก้ไข: ฉันพยายามเปลี่ยน Skeleton skel เป็น Body skel ซึ่งฉันคิดว่าเป็นวัตถุผู้ติดต่อสำหรับ kinect SDK 2.0 อย่างไรก็ตามฉันมีข้อผิดพลาดเมื่อพยายามรับตำแหน่งของร่างกาย:

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

ฉันได้รับข้อผิดพลาดเมื่อเรียกใช้ฟังก์ชันตำแหน่งสำหรับโครงร่าง ฉันจะดึง X, Y, Z ของโครงกระดูกใน sdk 2.0 ได้อย่างไร? ฉันพยายามเปลี่ยนสามบรรทัดด้านบนเป็น:

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

แก้ไข: โดยทั่วไปฉันจัดการเพื่อจัดเก็บไฟล์ bvh หลังจากรวม bodyBasicsWPF และ kinect2bvh อย่างไรก็ตามดูเหมือนว่าโครงกระดูกที่ฉันจัดเก็บนั้นไม่มีประสิทธิภาพ มีการเคลื่อนไหวที่แปลกในข้อศอก ฉันพยายามที่จะเข้าใจถ้าฉันมีการเปลี่ยนแปลงบางสิ่งบางอย่างในแฟ้มkinectSkeletonBVH.cp โดยเฉพาะอย่างยิ่งการเปลี่ยนแปลงในการวางแนวแกนร่วมสำหรับรุ่น kinect 2 คืออะไร ฉันจะเปลี่ยนบรรทัดต่อไปนี้: ฉันพยายามที่จะเปลี่ยนบรรทัดที่มีskel.BoneOrientations[JointType.ShoulderCenter].AbsoluteRotation.Quaternion; skel.JointOrientations[JointType.ShoulderCenter].Orientationฉันถูกไหม? ฉันใช้รหัสต่อไปนี้เพื่อเพิ่มข้อต่อไปยังวัตถุ 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);

ฉันไม่สามารถเข้าใจได้ว่าthe axis for every Jointจะคำนวณได้จากที่ไหนภายในโค้ด


9
ฉันข้ามปัญหานี้ แต่ถ้าคุณมีวิธีแก้ปัญหามันดีที่จะโพสต์ไว้ที่นี่ไม่ใช่เฉพาะสำหรับฉันเนื่องจากฉันสังเกตเห็นผู้คนมากมายที่ค้นหาการเคลื่อนไหวในการจัดเก็บในไฟล์ bvh
Jose Ramon

ฉันสามารถจัดเก็บข้อมูล Kinect v1 และ v2 สำหรับไฟล์ txt ไฟล์ BVH นี้เป็นสิ่งที่ฉันเพิ่งอ่านและจะเป็นคุณสมบัติที่ฉันจะเพิ่มลงในซอฟต์แวร์การได้มาของเรา หากคุณมีความสนใจในไฟล์ * .txt เพียงแค่แจ้งให้เราทราบ ฉันยังไม่มีวิธีการแก้ปัญหา BVH ที่เหมาะสม
16per9

2
ตรวจสอบ: pterneas.com/2014/03/13/…
Khaled.K

1
ฉันมีวิธีในการเขียนสตรีม Kinect v1 และ Kinect v2 อย่างเหมาะสมลงใน txt บางทีถ้าคุณใช้มันคุณสามารถตรวจสอบอีกครั้งจากนั้นไฟล์ bvh ของคุณสำหรับการทดสอบเดียวกัน ตรวจสอบประวัติของฉันสำหรับข้อมูลเพิ่มเติม
16per9

1
@ Khaled.K หากลิงก์ที่คุณโพสต์ตอบไว้คุณคิดจะสร้างมันให้เป็นคำตอบสำหรับคำถามนี้หรือไม่ (ต่อคำถามเมตานี้ )
Matt Thomas

คำตอบ:


2

รหัสที่คุณใช้สำหรับKinect 1.0จะได้รับBVHใช้ไฟล์ข้อมูลข้อต่อเวกเตอร์สร้างกระดูกโดยการอ่านโครงกระดูก

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

ที่มา: NguyênLêĐặng - Kinect2BVH.V2

ยกเว้นในKinect 2.0 , Skeleton Skeletonได้ถูกแทนที่ด้วยBody class ดังนั้นคุณต้องเปลี่ยนมันเพื่อจัดการกับร่างกายแทนและรับข้อต่อโดยทำตามขั้นตอนที่ยกมาด้านล่าง

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

นอกจากนี้เรายังเพิ่มรายการเนื้อหาที่จะบันทึกข้อมูลที่เกี่ยวข้องกับร่างกาย / โครงกระดูกทั้งหมด หากคุณพัฒนาสำหรับ Kinect เวอร์ชัน 1 คุณสังเกตว่าคลาส Skeleton ถูกแทนที่ด้วยคลาส Body จำ MultiSourceFrameReader ได้หรือไม่ คลาสนี้ให้เราเข้าถึงทุกกระแสรวมถึงกระแสร่างกาย! เราเพียงแค่ต้องการให้เซ็นเซอร์รู้ว่าเราต้องการฟังก์ชั่นการติดตามร่างกายโดยการเพิ่มพารามิเตอร์เพิ่มเติมเมื่อเริ่มต้นเครื่องอ่าน:

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

_reader.MultiSourceFrameArrived += Reader_MultiSourceFrameArrived;

กระบวนการ Reader_MultiSourceFrameArrived จะถูกเรียกใช้ทุกครั้งที่มีเฟรมใหม่ เราจะระบุสิ่งที่จะเกิดขึ้นในแง่ของข้อมูลร่างกาย:

  1. รับการอ้างอิงถึงเฟรมร่างกาย
  2. ตรวจสอบว่าเฟรมตัวถังเป็นโมฆะหรือไม่ - สิ่งนี้สำคัญมาก
  3. เริ่มต้นรายการ _bodies
  4. เรียกใช้เมธอด GetAndRefreshBodyData เพื่อคัดลอกข้อมูลร่างกายลงในรายการ
  5. วนรอบรายการของร่างกายและทำสิ่งที่ยอดเยี่ยม!

อย่าลืมตรวจสอบค่าว่างเสมอ Kinect ให้คุณประมาณ 30 เฟรมต่อวินาที - อาจเป็นโมฆะหรือขาดหายไป! นี่คือรหัสจนถึง:

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

นี่ไง! ตอนนี้เราสามารถเข้าถึงร่าง Kinect ได้ ขั้นตอนต่อไปคือการแสดงข้อมูลโครงกระดูกบนหน้าจอ ร่างกายแต่ละคนประกอบด้วย 25 ข้อต่อ เซ็นเซอร์ให้ข้อมูลตำแหน่ง (X, Y, Z) และข้อมูลการหมุนสำหรับแต่ละรายการ ยิ่งไปกว่านั้น Kinect ยังช่วยให้เราทราบว่าข้อต่อได้รับการติดตามตั้งสมมติฐานหรือไม่ติดตาม เป็นวิธีปฏิบัติที่ดีในการตรวจสอบว่ามีการติดตามร่างกายก่อนที่จะทำหน้าที่สำคัญใด ๆ หรือไม่

รหัสต่อไปนี้แสดงวิธีที่เราสามารถเข้าถึงข้อต่อต่างๆของร่างกาย:

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

ที่มา: Vangos Pterneas Blog - KINECT สำหรับ WINDOWS VERSION 2: BODY TRACKING

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.