2017-02-08 4 views
2

J'essaie de capturer des images de la caméra et des données de mouvement associées. Pour la synchronisation, j'utilise des horodatages. La vidéo et le mouvement sont écrits dans un fichier puis traités. Dans ce processus, je peux calculer le décalage des images de mouvement pour chaque vidéo.iOS: Synchronisation des images de la caméra et des données de mouvement

Éteint Les données de mouvement et les données vidéo pour le même horodatage sont décalées l'une de l'autre d'un temps différent de 0,2 seconde à 0,3 seconde. Ce décalage est constant pour une vidéo mais varie d'une vidéo à l'autre. Si c'était le même décalage chaque fois que je serais en mesure de soustraire une valeur calibrée mais ce n'est pas le cas.

Existe-t-il un bon moyen de synchroniser les horodatages? Peut-être que je ne les enregistre pas correctement? Existe-t-il un meilleur moyen de les amener au même cadre de référence?

retourne CoreMotion TimeStamps par rapport à la disponibilité du système, donc j'ajouter un DÉCALAGE pour obtenir le temps 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]; 

Pour obtenir des cadres horodatages avec une grande précision que je utilise AVCaptureVideoDataOutputSampleBufferDelegate. Il est compensé en temps unix aussi:

-(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

Salut servalex, avez-vous été capable de surmonter cela? –

+0

@ ShaiBen-Tovim, a ajouté une réponse. Malheureusement, je n'ai pas trouvé quelque chose d'utile dans l'API, donc je devais pirater. – servalex

Répondre

0

La meilleure solution que j'ai pu trouver à ce problème a été pour lancer un tracker de fonction sur la vidéo enregistrée, choisissez l'une des caractéristiques fortes et tracer la vitesse de c'est un mouvement le long de l'axe X, puis corréler ce tracé avec les données de l'accéléromètre Y.

Lorsqu'il y a 2 tracés similaires décalés les uns par rapport aux autres, il existe une technique appelée cross-correlation qui permet de trouver le décalage.

Il y a un inconvénient évident de cette approche: elle est lente car elle nécessite un traitement vidéo.

+0

C'est un énorme marteau pour cet ongle! Avez-vous essayé différents paramètres pour 'deviceMotionUpdateInterval'? La fréquence d'échantillonnage du CM peut-elle être trop 'lente' pour la fréquence d'images vidéo? Peut-être possible des erreurs d'arrondi cachées dans les maths de décalage ou de temps? –