【问题标题】:How to record frames of Leap Motion for Hand Tremor Tracking in C#?如何在 C# 中记录手震跟踪的 Leap Motion 帧?
【发布时间】:2016-05-27 06:50:01
【问题描述】:

我已经在 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");
    }

}

}

【问题讨论】:

  • 展示你的尝试
  • 我已经编辑了这篇文章
  • 在 LeapMotion SDK 中有一个示例可以记录你的手部动作并回放。我认为这就是你要找的。我在 Unity3d 资产上的 C# 中找到了它们。

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


【解决方案1】:

我遇到了同样的问题,我在 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

仍然需要根据 SDK 文档包含原始 LeapC.dll。

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多