Как именно мы вычисляем разницы по меткам времени?
Мы получаем временные метки в виде двойного значения для данных позы, изображения и точки - они не всегда выровнены - как рассчитать временное расстояние между двумя метками времени? Да, я знаю, как вычесть два двойных числа, но я совсем не уверен, что дельта соответствует времени.
2 ответа
У меня есть некоторые интересные временные данные, которые проливают свет на ваш вопрос, не давая точного ответа. Я пытался сопоставить рамки глубины с рамками изображений - так же, как многие люди публикуют под этим тегом Tango. Мои данные не совпадали точно, и я подумал, что были проблемы с моими проекционными матрицами и перепроецированием точек. Затем я проверил временные метки на своих кадрах глубины и кадрах изображения и обнаружил, что они отключены на целых 130 миллисекунд. Много! Даже при том, что я получал самое последнее изображение всякий раз, когда была доступна рамка глубины. Поэтому я вернулся, чтобы проверить только данные метки времени.
Я работаю в Native с кодом, основанным на примере point-cloud-jni. Для каждого из onXYZijAvailable(), onFrameAvailable() и onPoseAvailable() я выгружаю информацию о времени. В случаях XYZ и Frame я копирую возвращенные данные в статический буфер для дальнейшего использования. Для этого теста я игнорирую буферизованный кадр изображения, и данные глубины XYZ отображаются в обычном цикле отображения OpenGL примера кода. Захваченные данные выглядят так:
callback type : systime : timestamp : last pose
I/tango_jni_example( 3247): TM CLK Img 5.420798 110.914437 110.845522
I/tango_jni_example( 3247): TM CLK XYZ 5.448181 110.792470 110.845522
I/tango_jni_example( 3247): TM CLK Pose 5.454577 110.878850
I/tango_jni_example( 3247): TM CLK Img 5.458924 110.947708 110.878850
I/tango_jni_example( 3247): TM CLK Pose 5.468766 110.912178
Системное время от std::chrono::system_clock::now(), запущенного внутри каждого обратного вызова. (Смещено на время начала при запуске приложения.) Временная метка - это фактические данные временной метки из структуры XYZij, изображения или позы. Для глубины и изображения я также перечисляю самую последнюю временную метку позы (от начала обслуживания до устройства с заданным временем 0.0). Быстрый анализ около 2 минут выборочных данных приводит к следующим первоначальным выводам:
Pose data is captured at VERY regular intervals of 0.033328 seconds.
Depth data is captured at pretty regular intervals of 0.2 seconds.
Image data is captured at odd intervals
with 3 or 4 frames at 0.033 seconds
then 1 frame at about 0.100 seconds
often followed by a second frame with the same timestamp
(even though it is not reported until the next onFrameAvailable()?)
Это фактические данные метки времени в возвращенных структурах. Реальный?" Истекшее время между обратными вызовами намного более изменчиво. Обратный вызов позы срабатывает в любом месте от 0,010 до 0,079 секунд, даже несмотря на то, что временные метки позы являются твердыми на 0,033. Обратный вызов изображения (кадра) запускается 4 раза с 0,025 до 0,040, а затем дает одну длинную паузу около 0,065. Вот где два изображения с одинаковой временной меткой возвращаются в последовательных вызовах. Похоже, камера пропускает кадр?
Таким образом, чтобы сопоставить глубину, изображение и позу, вам действительно нужно буферизовать несколько возвратов с соответствующими им временными метками (кольцевой буфер?), А затем сопоставить их с тем значением, которое вы хотите использовать в качестве основного. Время позы являются наиболее стабильными.
Примечание. Я не пытался получить позу за определенное "промежуточное" время, чтобы проверить, интерполируется ли возвращаемая поза между значениями, заданными функцией onPoseAvailable().
У меня есть файл logcat и различные выдержки из awk. Я не уверен, как опубликовать эти (1000 строк).
Я думаю, что основной вопрос заключается в том, как синхронизировать данные позы, глубины и цвета изображения в одном кадре. Таким образом, чтобы ответить на это, на самом деле есть два шага
- Синхронизируйте позу либо с цветным изображением, либо с глубиной: для этого самый простой способ - использовать функцию TangoService_getPoseAtTime, которая в основном дает вам возможность запрашивать позу с определенной временной меткой. то есть, у вас есть доступное облако точек глубины, и оно дает вам временную метку этого кадра глубины, тогда вы можете использовать временную метку облака точек глубины, чтобы запросить соответствующую позу.
- Синхронизируйте цветное изображение и изображение глубины: в настоящее время вам придется буферизовать либо облако точек глубины, либо цветное изображение на уровне приложения и на основе одной из временных меток запрашивать данные другого в буфере. В структуре данных TangoXYZij есть имя поля color_image, и в комментарии говорится, что оно зарезервировано для будущего использования, поэтому встроенная функция синхронизации может появиться в будущих выпусках.