Получение данных от Kinect за определенное время

Есть ли способ получить данные, такие как расположение соединения, от 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: at SkeletalTracking.MainWindow.sensor_AllFramesReady(Отправитель объекта, AllFramesReadyEventArgs e)

Будет this.Recorder.Record(skeletonFrame); начать запись или мне нужно инициализировать и объявить или вызвать одну из функций, чтобы начать запись и запросить имя файла для сохранения?

Позволяет ли воспроизведение данных извлекать конкретные значения меток времени и данные, связанные с этими метками времени?

3 ответа

Kinect Toolbox предлагает функции записи и воспроизведения скелетных данных. Я не уверен, поддерживает ли он режим "снимка", когда вы говорите, что он берет только текущий кадр, но код, безусловно, может быть адаптирован для этого.

Вы можете свернуть свои собственные, настроив соответствующие проверки в вашем SkeletonFrameReady Перезвоните. Все данные скелета доступны для вас в SkeletonFrameReady Перезвоните. Вам просто нужно сохранить соответствующие данные в коллекции какого-либо типа - вы можете сохранить каждый скелет, или вы можете настроить таймер для проверки и захватывать их только за секунды - секунды.

Аналогичный вопрос и ответ был рассмотрен здесь: kinect C# нарисуйте и переместите скелет из сохраненных данных

Что-то еще, что вы можете попробовать сделать всю работу в таймере:

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 Toolbox (ссылка на который есть в первом абзаце) уже есть рекордер. Попробуйте сначала, чтобы увидеть, будет ли он делать то, что вы хотите.

Да, это возможно, я использовал 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);
}

Хорошо, вы записали кадры. Посмотрите на код кнопки воспроизведения, вы создали обработчик событий для ReplaySkeletonFrameReady, Помните? (this.Replay.SkeletonFrameReady += Replay_SkeletonFrameReady;)

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

Таким образом, в вашем SkeletonFrameReady вы получите записанный скелет, так что вы можете получить скелет и использовать сохраненные данные.

Ждать х секунд в C# проще всего

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

Другой способ - использовать объекты таймера и разрешить их отключение, а также прочитать статическое значение формы в циклическом коде, проверить это логическое значение, если что-то должно быть записано или нет

Другие вопросы по тегам