我正在尝试从相机和相关的运动数据中捕获帧.
为了同步我正在使用时间戳.视频和动作被写入文件然后进行处理.在那个过程中,我可以计算每个视频的运动帧偏移.
为了同步我正在使用时间戳.视频和动作被写入文件然后进行处理.在那个过程中,我可以计算每个视频的运动帧偏移.
结果运动数据和相同时间戳的视频数据彼此偏移0.2秒到0.3秒的不同时间.
该偏移对于一个视频是恒定的,但是从视频到视频是不同的.
如果它是相同的偏移,每次我能够减去一些校准值,但事实并非如此.
是否有一种同步时间戳的好方法?
也许我没有正确录制它们?
有没有更好的方法将它们带到同一参照系?
CoreMotion返回相对于系统正常运行时间的时间戳,因此我添加了偏移以获得unix时间:
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; ... }
解决方法
我能找到这个问题的最佳解决方案是
要在录制的视频上运行一个特征跟踪器,选择一个强大的特征并绘制它沿着X轴移动的速度,然后将该图与加速度计Y数据相关联.
要在录制的视频上运行一个特征跟踪器,选择一个强大的特征并绘制它沿着X轴移动的速度,然后将该图与加速度计Y数据相关联.
当有两个相似的图沿横坐标彼此偏移时,有一种叫做cross-correlation的技术可以找到偏移量.
这种方法有一个明显的缺点 – 它需要一些视频处理,因此速度很慢.