如何在 C# 中记录用于手部震颤跟踪的跳跃运动帧

本文关键字:跟踪 震颤 跳跃 运动 手部 用于 记录 | 更新日期: 2023-09-27 18:34:41

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

如何在 C# 中记录用于手部震颤跟踪的跳跃运动帧

我遇到了同样的问题,我不得不在框架中遵循解决方案.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;
    }
}

因此,交互框必须在交互框中可序列化.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仍然需要包含在内。

希望有帮助。