【问题标题】:Obtaining data from Kinect for specific time从 Kinect 获取特定时间的数据
【发布时间】:2012-11-16 22:20:57
【问题描述】:

有没有办法从 Kinect 获取特定时间的数据,例如关节的位置?我想在我选择用于其他计算的特定时间内获取并保存这些数据。例如在运行程序后的时间 = 5 秒和运行程序后的时间 = 10 秒时获取头部的位置数据并将其保存到变量中。

运行时出错: 这是部分代码....

    void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
    {
        if (closing)
        {
            return;
        }

        //Get a skeleton
        Skeleton first = GetFirstSkeleton(e);

        if (first == null)
        {
            return;
        }

        GetCameraPoint(first, e);

        using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
        {
            if (skeletonFrame == null)
            {
                return;
            }

            this.Recorder.Record(skeletonFrame); // I get an error after the RGB camera view freezes

        }
         // some more stuff 
     }

这是我收到的错误消息:

System.NullReferenceException 未处理 Message=对象引用未设置为对象的实例。 Source=SkeletalTracking StackTrace: 在 SkeletalTracking.MainWindow.sensor_AllFramesReady(Object sender, AllFramesReadyEventArgs e)

this.Recorder.Record(skeletonFrame); 会开始录制还是我需要初始化并声明或调用其中一个函数来开始录制并询问要保存到的文件的名称?

数据的回放是否允许我提取特定的时间戳值以及在这些时间戳处关联的数据?

【问题讨论】:

    标签: time position kinect


    【解决方案1】:

    在 C# 中等待 x 秒最简单的方法是

    System.Threading.Thread.Sleep(x000);//where x is the time in seconds for which you want app to wait
    

    例子:

    System.Threading.Thread.Sleep(4000);//will wait for 4 seconds
    

    另一种方法是使用计时器对象并启用禁用它们,并在循环代码中读取表单静态值,检查该布尔值是否必须记录某些内容

    【讨论】:

      【解决方案2】:

      是的,有可能,我为此使用了Kinect.Toolbox 该库具有 Recorder 和 Replay 类,允许您将帧录制到磁盘并重播保存的帧。 我成功使用了这个库,如果你想要一些示例代码,请告诉我。

      这个讨论越来越大,我会编辑这个来解释一些问题

      编辑 1. KINECT.TOOLBOX快速教程

      在您的应用程序中创建 3 个按钮(开始录制、停止录制、开始重播)

      Form.cs 代码

          Stream recordStream;
          KinectRecorder Recorder;
          KinectReplay Replay;
      

      开始录制按钮的代码:

       protected void StartRecord(object sender, RoutedEventArgs e)
          {
              string generatedName = Guid.NewGuid().ToString();
              string recordStreamPathAndName = @"C:\" + generatedName + ".recorded";            
              this.recordStream = File.Create(recordStreamPathAndName);
              this.Recorder = new KinectRecorder(KinectRecordOptions.Color | KinectRecordOptions.Skeletons, recordStream);
          }
      

      停止录制按钮的代码

       if (Recorder != null)
              {
                  Recorder.Stop();
                  Recorder = null;
              }
      

      重播按钮代码

      try
      {
          recordStream = File.OpenRead(this.recordStreamPathAndName);
      }
      catch (Exception ex)
      {
          throw ex;
      }
      
          this.Replay = new KinectReplay(recordStream);
          this.Replay.ColorImageFrameReady += Replay_ColorImageFrameReady;
          this.Replay.SkeletonFrameReady += Replay_SkeletonFrameReady;
          this.Replay.Start();
      }
      

      这里我们启用颜色和骨架记录器,现在我们只记录骨架数据,例如海豚。 在您的 SkeletonFrameReady 事件处理程序中,您需要执行类似的操作

      using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
      {
          if (skeletonFrame == null)
              return;
              // any other validations...
          this.Recorder.Record(skeletonFrame);
      }
      

      好的,你记录了帧。 查看 Replay 按钮代码,您为ReplaySkeletonFrameReady 创建了一个事件处理程序,还记得吗? (this.Replay.SkeletonFrameReady += Replay_SkeletonFrameReady;)

          void Replay_SkeletonFrameReady(object sender, ReplaySkeletonFrameReadyEventArgs e)
          {
              // do your stuff.
          }
      

      所以在你的 SkeletonFrameReady 中你会得到记录的骨架,所以你可以得到骨架并使用保存的数据。

      【讨论】:

      • 如果你只想要一些帧的快照,你可以将这些帧序列化到内存中。 stackoverflow.com/questions/10390356/… 稍后再检索。
      • 当然,代码将不胜感激。我如何将它合并到 SDK 示例代码中的骨骼跟踪代码中。我正在使用该代码。是否必须手动运行 Kinect Toolbox 才能保存数据,或者有没有办法在运行骨骼跟踪代码时自动抓取数据?
      • 在我的例子中,我只是引用了 Kinect.Toolbox 项目,并在需要时实例化了 Recorder 或 Replay 并使用它,就像 Kinect.Toolbox 提供的示例代码一样。您也可以这样做,因此,您仍然在使用 skeletal trackin 项目,只需在其上引用 Kinect.Toolbox 并使用它。试试看,如果你没有成功,请告诉我,我会帮你的。
      • 我已经下载了 Kinect.Toolbox 文件并将我的项目的引用添加到 Kinect.Toolbox。我看到了与记录器相关的示例代码,并重放了我可以从中提取的每个数据流。我如何以及在我的骨骼跟踪项目中调用什么来记录以及放置此代码的最佳位置是哪里?如何将我录制的内容保存到文件中?然后从记录的内容中提取值?
      • 伙计,10 分钟前有人建议你查看 kinect 工具箱code samples,现在你要我写代码?请查看示例,它们可以回答您的所有问题。
      【解决方案3】:

      Kinect Toolbox 提供骨骼数据的记录和回放功能。我不确定它是否支持“快照”模式,您可以在其中告诉它只拍摄当前帧,但代码当然可以适应这样做。

      您可以通过在 SkeletonFrameReady 回调中设置适当的检查来滚动您自己。在SkeletonFrameReady 回调中,您可以使用所有骨架数据。您只需将适当的数据保存到某种类型的集合中——您可以保存每个骨架,或者您可以设置一个计时器来检查并仅在 ??- 秒内捕获它们。

      此处解决了类似的问题和答案: kinect c# draw and move skeleton from saved data

      您可以尝试的其他方法是在计时器中完成所有工作:

      private void Window_Loaded(object sender, RoutedEventArgs e)
      {
          _savedSkeletons = new List<Skeleton>();
      
          _timer = new DispatcherTimer();
          _timer.Interval = TimeSpan.FromSeconds(5);
          _timer.Tick += (s, o) =>
          {
              using (SkeletonFrame skeletonFrame = KinectSensorManager.KinectSensor.SkeletonStream.OpenNextFrame(15))
              {
                  if (skeletonFrame == null || skeletonFrame.SkeletonArrayLength == 0)
                      return;
      
                  // resize the skeletons array if needed
                  if (_skeletons.Length != skeletonFrame.SkeletonArrayLength)
                      _skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
      
                  // get the skeleton data
                  skeletonFrame.CopySkeletonDataTo(_skeletons);
      
                  foreach (var skeleton in _skeletons)
                  {
                      if (skeleton.TrackingState != SkeletonTrackingState.Tracked)
                          continue;
      
                      _savedSkeletons.Add(skeleton);
                  }
              }
          };
      
          _timer.Start();
      }
      

      _savedSkeletons 变量每 5 秒存储一次骨架。如果您想将它们保存到文件中,您可以序列化数据并通过文件流将其写出(许多关于如何序列化和输出对象的示例)。

      上面的代码是一个简单的例子,只是存储了Skeleton 对象。为了实现您的所有目标,您可能需要存储其他信息——例如时间戳。您需要创建一个自定义类来存储您想要的所有信息并存储这些对象。

      请记住,Kinect 工具箱(在第一段中链接)已经有一个记录器。先试试看它是否会做你想做的事。

      【讨论】:

      • 如果我正在运行骨骼跟踪示例代码并希望在骨骼跟踪示例代码中进行修改以自动捕获该数据,我将如何使用计时器保存数据?
      • 我已经更新了我的答案,提供了更多详细信息。
      • 感谢您的更新。如果我要使用此代码,它是否与骨骼跟踪示例代码中的功能相同?我已经尝试使用该确切的代码,但它给出了一个关于不知道 _savedSkeletons 在那种情况下是什么的错误已经。我希望能够存储它,以便调用某些值来计算关节和质心的速度(使用头肩关节)。
      • _savedSkeleton_skeletons_timer 都是我之前在课堂上声明的全局变量,只是没有包含在示例代码中。您需要在全球范围内声明它们。如果您在计时器回调中执行代码,您可以将它放在对您有意义的任何地方。因为您需要速度,所以您需要创建自己的类来存储关节数据和时间戳。 Kinect Toolbox 类就是一个很好的例子。
      • 这些是什么变量类型,我在声明它们时将它们设置为什么?那么这些代码行最好放在代码的 FramesReady 部分中吗?我如何创建一个类来存储这些数据?谢谢
      猜你喜欢
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      相关资源
      最近更新 更多