OpenCV VideoWriter Problème De Framerate
Que j'essaie d'enregistrer de la vidéo à partir d'un 1080p webcam dans un fichier. J'ai tenu une minuterie dans la vidéo et dans tous les procès, le timestamp signalé par un lecteur vidéo (VLC est ce que j'ai utilisé) n'est pas synchronisé avec le temps dans la vidéo. C'est toujours éteint quelques secondes (généralement en vidéo de la minuterie est plus rapide que joueur signalé temps).
Comme on le voit ci-dessous, j'ai mis en place le programme C++ pour capturer de la vidéo dans un thread, et de les enregistrer dans un autre thread. Cela fonctionne bien tant que mon utilisation de l'UC est ~200% (max possible?). Je suis sur un Macbook Air w/OS X 10.8 @ 1.8 GHz Intel Core i7.
J'ai essayé de changer le taux de rafraîchissement à 15fps et que les résultats en très agitées/ralentir la vidéo. J'ai aussi essayé de réglage CV_CAP_PROP_FRAME_WIDTH
& CV_CAP_PROP_FRAME_HEIGHT
à une résolution plus faible et il en résulte lent vidéo. Il semble que 1080p @ 30fps résultats dans le bon équilibre de la vidéo, mais il est encore joue toujours plus vite qu'il est censé. J'ai aussi essayé de mettre en waitKey(10);
après record << frame;
mais il n'a pas d'incidence sur quoi que ce soit.
Des recommandations sur la façon de faire de la vidéo du match à l'heure?
Merci!
Aakash
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <boost/thread.hpp>
using namespace cv;
void captureFunc(Mat *frame, VideoCapture *capture){
for(;;){
//get a new frame from camera
(*capture) >> (*frame);
}
}
int main(int, char**)
{
VideoCapture capture(0); //open the default camera
if( !capture.isOpened() ) {
printf("Camera failed to open!\n");
return -1;
}
capture.set(CV_CAP_PROP_FPS,30); //set capture rate to 30fps
Mat frame;
capture >> frame; //get first frame for size
//initialize recording of video
VideoWriter record("test.avi", CV_FOURCC('D','I','V','X'), 30, frame.size(), true);
if( !record.isOpened() ) {
printf("VideoWriter failed to open!\n");
return -1;
}
boost::thread captureThread(captureFunc, &frame, &capture); //start capture thread
sleep(1); //just to make sure capture thread is ready
for(;;)
{
//add frame to recorded video
record << frame;
}
return 0;
}
J'ai essayé de 25 FPS et en utilisant que le codec XVID. Pour les vidéos d'environ 1,5 minutes, il fonctionne très bien (certaines parties sont en quelques secondes rapides et d'autres lente, de sorte qu'il représente en moyenne), mais dans quelque chose de plus ou moins longue VLC lire la vidéo de 3 à 6 secondes de plus qu'il est en réalité (ex. Minuterie dans la vidéo montre 5 minutes s'est écoulée, mais VLC va jouer pendant 5 minutes et 6 secondes)
Dans mon test d'enregistrement à 5 min de la vidéo, le temps a été la synchronisation de jusqu'à ce que, après environ 3 minutes et 10 secondes. Par la suite, l'écart obtenu jusqu'à 6 secondes à la fois, en finissant à environ 5 secondes de la synchronisation.
OriginalL'auteur Aakash Patel | 2013-06-13
Vous devez vous connecter pour publier un commentaire.
J'ai résolu mon problème après un peu de débogage; il avait un problème avec VideoWriter pointilleux sur la vitesse à laquelle les images ont été nourris.
+1 encore pour répondre à la question. Mais j'ai remarqué que vous pouvez avoir une condition de concurrence dans votre solution, puisque la caméra-l'acquisition de thread peut actualiser le Tapis "cadre" dans le même temps VideoWriter est d'y accéder.
L'article est excellent, mais il serait mieux si vous pouvez l'écrire ici et juste donner un lien vers votre site web. Si vous avez un changement d'url, les données sont perdues!
Dans le cas où le lien meurt, l'écriture dit en fait exactement ce que vous attendez: que le videowriter "writeFrame () doit être appelé à l'intervalle de la FPS spécifié dans le format que vous avez initialisé avec. Du sens.
cela ne fait aucun sens du tout, si je voulais le faire en deux heures de vidéo pour laquelle j'ai pu générer les images en 10 minutes, je dois attendre deux heures pour faire ma sortie? veeery bizarre.
OriginalL'auteur Aakash Patel
Vous avez besoin pour synchroniser votre lire et écrire les fonctions. Votre code se lit aussi vite que possible, et écrit aussi vite que possible. Votre vidéo de sortie ressemble probablement lente parce que l'écriture de la sortie arrive plus vite que la lecture à l'entrée (depuis
capture >>
est en attente de votre appareil photo), et de plusieurs cadres identiques sont enregistrées.Écrit sans attente ou à la synchronisation signifie que vous pouvez écrire le même contenu plusieurs fois (ce que je pense c'est le cas ici), ou de perdre des images.
Si vous voulez garder des threads, vous pouvez, mais vous aurez besoin pour faire de votre processus d'écriture d'attendre jusqu'à ce qu'il y a quelque chose nouveau à écrire.
De même, pour éviter de perdre des images ou de l'écriture corrompu cadres, vous avez besoin du processus de lecture d'attendre jusqu'à ce que l'écrit est fait, de sorte que
frame
peut être en toute sécurité écrasé.Car les threads besoin d'attendre les uns des autres de toute façon, il y a peu de point dans les discussions.
Je préfère recommander ce moyen beaucoup plus simple:
Si vous avez besoin de parallélisme, vous aurez besoin de beaucoup plus complexe mécanisme de synchronisation, et peut-être une sorte de fifo pour vos images.
OriginalL'auteur Gauthier