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