如何在C#中记录Leap Motion用于手部震颤跟踪的帧?

时间:2016-02-16 06:06:48

标签: c# youtube signal-processing frame leap-motion

我已经在Youtube上看到了Leap Motion Tremor Recognition,并开始使用Leap Motion在C#中进行信号处理来构建此应用。我在第一步遇到了一些问题。我不知道如何每秒获取和记录一些手部动作帧。在这种情况下,我想在10秒内录制它。我不知道图书馆必须用什么来记录这个。

希望有人帮我解释并分享如何在C#中编写代码...谢谢

这是我尝试过的代码,但我没有构建和运行它,所以我认为它不起作用。有人可以帮我查一下吗?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
using System.Diagnostics;
using Leap;

namespace map3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, ILeapEventDelegate
{

    private Controller controller = new Controller();
    Leap.Frame frame;

    //getting data from a frame
    HandList hands;
    PointableList pointables;
    FingerList fingers;
    ToolList tools;


    private LeapEventListener listener;
    private Gesture gesture = new Gesture();
    private String direction;
    Leap.Frame gestureFrame;
    Leap.Frame fingerFrame;

    private long timestamp;

    private Boolean isClosing = false;
    private Boolean isPlaying = false;

    private Int64 lastFrameID = 0;

    Thread finger_thread, gesture_thread;

    public MainWindow()
    {
        InitializeComponent();
        main_window.ResizeMode = ResizeMode.NoResize;

        this.controller = new Controller();
        this.listener = new LeapEventListener(this);
        controller.AddListener(listener);
        processFrame(frame);

        //get timestamp
        float framePeriod = controller.Frame(0).Timestamp - controller.Frame(1).Timestamp;
        lbl_debug.Content = "Gesture";
    }

    private void processFrame(Leap.Frame frame)
    {
        if (frame.Id == lastFrameID)
            return;
        lastFrameID = frame.Id;

       //for have an ID of an entity from a different frame
        Hand hand = frame.Hand(handID);
        Pointable pointable = frame.Pointable(pointableID);
        Finger finger = frame.Finger(fingerID);
        Tool tool = frame.Tool(toolID);

        Thread.Sleep(10000);

        //to save frame to file
        byte[] serializedFrame = frame.Serialize;
        System.IO.File.WriteAllBytes ("frame.data", serializedFrame);
    }

    public void Deserialize() //to read multiple frame  from the saved file
    {
        Controller leapController = new Controller();
        using (System.IO.BinaryReader br =
            new System.IO.BinaryReader(System.IO.File.Open("file.data", System.IO.FileMode.Open)))
        {
            while (br.BaseStream.Position < br.BaseStream.Length)
            {
                Int32 nextBlock = br.ReadInt32();
                byte[] frameData = br.ReadBytes(nextBlock);
                Leap.Frame newFrame = new Leap.Frame();
                newFrame.Deserialize(frameData);
            }
        }

    }

    private void btn_start_click(object sender, RoutedEventArgs e)
    {
        startDetect();
    }


    private void startDetect()
    {
        //maplayer.Play();
        if (controller.IsConnected)
        {
            Leap.Frame frame = controller.Frame(); //the latest frame
            Leap.Frame previous = controller.Frame(1); //the previous frame
        }
        isPlaying = true;
        btn_start.Content = FindResource("Start"); //connecting to gui
    }

    delegate void LeapEventDelegate(string EventName);
    public void LeapEventNotification(string EventName)
    {
        if (this.CheckAccess())
        {
            switch (EventName)
            {
                case "onInit":
                    Debug.WriteLine("Init");
                    break;
                case "onConnect":
                    this.connectHandler();
                    break;
                case "onFrame":
                    if (!this.isClosing)
                        this.processFrame(this.controller.Frame());
                    break;

            }
        }
        else
        {
            Dispatcher.Invoke(new LeapEventDelegate(LeapEventNotification), new object[] { EventName });
        }
    }

    void connectHandler()
    {
        this.controller.SetPolicy(Controller.PolicyFlag.POLICY_IMAGES);
        this.controller.EnableGesture(Gesture.GestureType.TYPE_SWIPE);
        this.controller.Config.SetFloat("Gesture.Swipe.MinLength", 200.0f);
        this.controller.Config.Save();
    }


    void MainWindow_Closing(object sender, EventArgs e)
    {
        this.isClosing = true;
        this.controller.RemoveListener(this.listener);
        this.controller.Dispose();
    }

    private void ListView_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
    {

    }

    public int handID { get; set; }

    public int pointableID { get; set; }

    public int toolID { get; set; }

    public int fingerID { get; set; }
}

public interface ILeapEventDelegate
{
    void LeapEventNotification(string EventName);
}

public class FrameListener : Listener
{
    public void onFrame(Controller controller)
    {
        Leap.Frame frame = controller.Frame();
        Leap.Frame previous = controller.Frame(1);
    }
}

public class LeapEventListener : Listener
{
    ILeapEventDelegate eventDelegate;

    public LeapEventListener(ILeapEventDelegate delegateObject)
    {
        this.eventDelegate = delegateObject;
    }
    public override void OnInit(Controller controller)
    {
        this.eventDelegate.LeapEventNotification("onInit");
    }
    public override void OnConnect(Controller controller)
    {
        controller.SetPolicy(Controller.PolicyFlag.POLICY_IMAGES);
        controller.EnableGesture(Gesture.GestureType.TYPE_SWIPE);
        this.eventDelegate.LeapEventNotification("onConnect");
    }

    public override void OnFrame(Controller controller)
    {
        this.eventDelegate.LeapEventNotification("onFrame");
    }
    public override void OnExit(Controller controller)
    {
        this.eventDelegate.LeapEventNotification("onExit");
    }
    public override void OnDisconnect(Controller controller)
    {
        this.eventDelegate.LeapEventNotification("onDisconnect");
    }

}

}

1 个答案:

答案 0 :(得分:0)

我遇到了同样的问题,我在Frame.cs中找到了以下解决方案。

要序列化框架:

public byte[] Serialize
{
    get
    {
        BinaryFormatter bf = new BinaryFormatter();
        using (var ms = new MemoryStream())
        {
            bf.Serialize(ms, this);
            return ms.ToArray();
        }
    }
}

要反序列化框架:

public void Deserialize(byte[] arg)
{
    using (var ms = new MemoryStream())
    {
        BinaryFormatter bf = new BinaryFormatter();
        ms.Write(arg, 0, arg.Length);
        ms.Seek(0, SeekOrigin.Begin);
        Frame objArray = (Frame)bf.Deserialize(ms);
        this.Id = objArray.Id;
        this.Timestamp = objArray.Timestamp;
        this.CurrentFramesPerSecond = objArray.CurrentFramesPerSecond;
        this.InteractionBox = objArray.InteractionBox;
        this.Hands = objArray.Hands;
    }

}

因此,InteractionBox必须在InteractionBox.cs中可序列化:

[System.Serializable]
public struct InteractionBox{...}

如果您使用项目中源文件夹中的* .cs文件,则会出现问题。如果要在其他应用程序中反序列化框架,则应使用更新的源代码从源文件夹构建DLL。例如。在一个程序中记录帧,然后在另一个程序中播放。

csc /t:library /out:Leap.dll LeapC.cs Arm.cs Bone.cs CircularObjectBuffer.cs ClockCorrelator.cs Config.cs Connection.cs Controller.cs CopyFromLeapCExtensions.cs CopyFromOtherExtensions.cs CSharpExtensions.cs Device.cs DeviceList.cs DistortionData.cs DistortionDictionary.cs Events.cs FailedDevice.cs FailedDeviceList.cs Finger.cs Frame.cs Hand.cs IController.cs Image.cs ImageData.cs ImageFuture.cs InteractionBox.cs LeapQuaternion.cs LeapTransform.cs Logger.cs Matrix.cs MessageSeverity.cs ObjectPool.cs PendingImages.cs PooledObject.cs StructMarshal.cs TimeBracket.cs TransformExtensions.cs Vector.cs

原始的LeapC.dll仍然需要根据SDK文档进行添加。

希望有帮助。