2017-02-08 23 views
2

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

Выключает данные о движении и видеоданные на одну и ту же метку времени, сдвинуты друг от друга в разное время от 0,2 секунды до 0,3 с. Это смещение является постоянным для одного видео, но варьируется от видео к видео. Если бы это было такое же смещение каждый раз, когда я мог бы вычесть некоторое откалиброванное значение, но это не так.

Есть ли хороший способ синхронизации временных меток? Возможно, я не правильно их записываю? Есть ли лучший способ привести их к одной и той же системе координат?

CoreMotion возвращает временные метки относительно безотказной работы системы, так что я добавить смещение, чтобы получить Юниксовое время:

uptimeOffset = [[NSDate date] timeIntervalSince1970] - 
        [NSProcessInfo processInfo].systemUptime; 

CMDeviceMotionHandler blk = 
    ^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error){ 
     if(!error){ 
      motionTimestamp = motion.timestamp + uptimeOffset; 
      ... 
     } 
    }; 

[motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXTrueNorthZVertical 
                toQueue:[NSOperationQueue currentQueue] 
               withHandler:blk]; 

Чтобы получить кадры метки времени с высокой точностью, я использую AVCaptureVideoDataOutputSampleBufferDelegate. Это смещение UniX времени также:

-(void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection 
{ 
    CMTime frameTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer); 

    if(firstFrame) 
    { 
     firstFrameTime = CMTimeMake(frameTime.value, frameTime.timescale); 
     startOfRecording = [[NSDate date] timeIntervalSince1970]; 
    } 

    CMTime presentationTime = CMTimeSubtract(frameTime, firstFrameTime); 
    float seconds = CMTimeGetSeconds(presentationTime); 

    frameTimestamp = seconds + startOfRecording; 
    ... 
} 
+0

Hi servalex, вы когда-нибудь могли это преодолеть? –

+0

@ ShaiBen-Tovim, добавил ответ. К сожалению, я не нашел ничего полезного в API, поэтому пришлось взломать. – servalex

ответ

0

Лучшее решение, которое я смог найти к этой проблеме был запустить функцию отслеживания над записанным видео, выбрать одну из сильных черт и построить скорость это движение вдоль оси X, а затем корреляция этого графика с данными акселерометра Y.

Когда есть 2 похожих графика, которые смещены друг от друга по оси абсцисс, есть метод, называемый cross-correlation, который позволяет найти смещение.

Существует очевидный недостаток этого подхода - он медленный, так как требует некоторой обработки видео.

+0

Это один огромный молоток для этого гвоздя! Вы пробовали разные настройки для 'deviceMotionUpdateInterval'? Может ли частота выборки CM быть слишком «медленной» для частоты кадров видео? Может быть, возможны скрытые ошибки округления в смещении или математике времени? –