2011-02-02 15 views
12

Estoy tratando de escribir un programa para analizar expresiones emocionales como lágrimas. Como parte de mi rastreador, estoy usando OpenCV para grabar videos de muestra. Particularmente, no estoy seguro acerca de cómo elegir correctamente FPS (10FPS parece que debería funcionar). Tampoco estoy seguro de qué Códec que debo usar en OS X, he intentado todas las posibles CV_FOURCC de here también, pero devuelve el error siguiente:¿Cómo escribir un archivo de video con OpenCV?

Stream #0.0: Video: rawvideo, yuv420p, 640x480, q=2-31, 19660 kb/s, 90k tbn, 10 tbc 
Assertion failed: (image->imageSize == avpicture_get_size((PixelFormat)input_pix_fmt, image->width, image->height)), function writeFrame, file /opt/local/var/macports/build/_opt_local_var_macports_sources_rsync.macports.org_release_ports_graphics_opencv/work/OpenCV-2.2.0/modules/highgui/src/cap_ffmpeg.cpp, line 1085. 

hacer que todos tienen algo de código de trabajo con cvWriteFrame? Gracias por tomarse el tiempo para ver mi problema!

Para los interesados ​​todo el programa es:

#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 

int main (int argc, const char * argv[]) 
{ 
    CvCapture *capture; 
    IplImage *img; 
    int  key = 0; 
    CvVideoWriter *writer; 

    // initialize camera 
    capture = cvCaptureFromCAM(0); 
    // capture = cvCaptureFromAVI("AVIFile"); 

    // always check 
    assert(capture); 

    // create a window 
    cvNamedWindow("video", 1); 

    int color = 1; // 0 for black and white 

    // get the frame size 
    CvSize size = cvSize((int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH),(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT)); 

    writer = cvCreateVideoWriter(argv[1], -1 , 10 , size, color); 

    while(key != 'q') { 
     // get a frame 
     img = cvQueryFrame(capture); 

     // always check 
     if(!img) break; 

     cvWriteFrame(writer, img);   
     cvShowImage("video", img); 

     // quit if user press 'q' 
     key = cvWaitKey(5); 
    } 

    // free memory 
    cvReleaseVideoWriter(&writer); 
    cvReleaseCapture(&capture); 
    cvDestroyWindow("video"); 

    return 0; 
} 
+1

¿Qué plataforma/sistema operativo? –

+1

¿Puede editar la pregunta para incluir el mensaje de error impreso en la consola/terminal después del SIGABRT? Esto nos ayudaría a entender más sobre el error. – speciousfool

Respuesta

17

Eche un vistazo a here para los códecs recomendados a utilizar.

Básicamente:

  • Se puede utilizar en lugar de -1CV_FOURCC(...)sólo si estás en Windows (ver el manual). Como está en OSX, , no puede usarlo.
  • Uso CV_FOURCC('I', 'Y', 'U', 'V') para codificar utilizando yuv420p en un contenedor AVI sin comprimir - Este es el método recomendado
  • Si desea vídeo comprimido, a continuación, puede utilizar herramientas como ffmpeg para comprimir la salida AVI por OpenCV

La razón por la cual OpenCV no recomienda el uso de códecs de compresores es probablemente porque cada códec tiene una gran cantidad de opciones específicas de códec, y tratar con todos ellos a través de la interfaz de escritura de video de OpenCV sería imposible.

EDITAR

Tengo algunas bad news:

Unfortunately, we still have no working (i.e. native) video writer for Mac OS X. If you need video writing, you should currently configure for ffmpeg or xine and disable QuickTime.

Suena como es posible que tenga que volver a configurar y volver a compilar su biblioteca.

EDIT 2

Como alternativa, puede simplemente escribir cada fotograma en un archivo JPEG y, a continuación, unir esos archivos JPEG en una película utilizando ffmpeg (que deberían funcionar en OS/X). Esto es esencialmente lo que es MJPEG, de todos modos. Sin embargo, es probable que obtenga mejores tasas de compresión con los códecs que aprovechan la redundancia temporal (por ejemplo, MPEG4, H.264, etc.).

+0

Gracias por sus sugerencias. Sin embargo, lo he intentado con CV_FOURCC ('I ',' Y ',' U ',' V ') incluidos todos los FOURCC enumerados en el documento, pero sin éxito. ¿Existe alguna forma en OS X de mostrar el diálogo como lo hace Windows con -1 o CV_FOURCC_PROMPT? – CCS

+1

. mi respuesta actualizada. – misha

0

creo que la línea CV_FOURCC puede ser incorrecta. Un similar question sugiere utilizar -1 como un valor de prueba CV_FOURCC para indicarle las opciones de trabajo en su sistema.

¿Puedes intentar compilar el programa de esa pregunta y decirnos si usando un valor de -1 en lugar de V_FOURCC('M', 'J', 'P', 'G') escribe un archivo AVI?

+1

Queridos todos, gracias por los comentarios. He editado el valor a -1 en lugar de V_FOURCC ('M', 'J', 'P', 'G'). El programa ahora se puede ejecutar y salir con valor de estado: 0. Sin embargo, el programa guardó un archivo de película AVI (8 KB en el disco) que aparentemente está vacío. Estoy usando OS X/X Code/OpenCV 2.2. ¿Todos tienen algún código de trabajo con cvWriteFrame? ¡Gracias por tomarse el tiempo para ver mi problema! " – CCS

+0

Tengo el mismo problema que @CCS – Lepi

+0

Voto abajo porque esto no parece responder a la pregunta. – JohnAllen

0

Creo que es por el tamaño del video - pruebe con otros, más comunes como 640X480 o 320X240.

Funciona para mí.

3

La afirmación sugiere que hay una discrepancia de tamaño entre la imagen que se envía a la grabadora de video y el tamaño especificado al inicializar la grabadora de video. Sugeriría agregar algunas declaraciones de depuración de la siguiente manera:

cout << "Video Size: " << size.width << "," << size.height << endl; 
cout << "Image Size: " << img.cols << "," << img.rows << endl; 

Eso debería ayudarlo a determinar si los tamaños son diferentes.

Con respecto a la pregunta fourcc, parece que está usando cap_ffmpeg en lugar de cap_qtkit. Puede intentar recompilar con ffmpeg off, ya que la versión qtkit de la captura funciona bastante bien en OS X. En lugar de usar macports, puede descargar directamente opencv2.2 desde sourceforge y usar ccmake para configurar opencv para que no use ffmpeg, en ese caso caso qtkit será el predeterminado.

Si usa qtkit, entonces necesita usar el fourcc ('j', 'p', 'e', ​​'g');

La velocidad de cuadro debe coincidir con la velocidad de cuadro de la entrada. Puede usar las propiedades para obtener la velocidad de fotogramas similar a la forma en que obtuvo el ancho y la altura del cuadro; sin embargo, dado que está capturando desde la cámara, probablemente deba probar la tasa de captura utilizando un temporizador en su código y estimando desde ese.

Aquí es un ejemplo basado en starter_video.cpp que trabajará con QTKit:

/* 
* starter_video_write.cpp 
* 
* Created on: Nov 23, 2010 
*  Author: Ethan Rublee 
* Modified on: Aug 3, 2011 by David Cooper 
* 
* A starter sample for using opencv, get a video stream and display the images 
* easy as CV_PI right? 
* edited to add writing capability for OS X using qtkit. 
*/ 
#include "opencv2/highgui/highgui.hpp" 
#include <iostream> 
#include <vector> 
#include <stdio.h> 

using namespace cv; 
using namespace std; 



//hide the local functions in an anon namespace 
namespace { 
    void help(char** av) { 
     cout << "\nThis program justs gets you started reading images from video\n" 
      "Usage:\n./" << av[0] << " <video device number>\n" 
      << "q,Q,esc -- quit\n" 
      << "space -- save frame\n\n" 
      << "\tThis is a starter sample, to get you up and going in a copy pasta fashion\n" 
      << "\tThe program captures frames from a camera connected to your computer.\n" 
      << "\tTo find the video device number, try ls /dev/video* \n" 
      << "\tYou may also pass a video file, like my_vide.avi instead of a device number" 
      << endl; 
    } 

    int process(VideoCapture& capture) { 
     int n = 0; 
     char filename[200]; 
     string window_name = "video | q or esc to quit"; 
     cout << "press space to save a picture. q or esc to quit" << endl; 
     namedWindow(window_name, CV_WINDOW_KEEPRATIO); //resizable window; 
     Mat frame; 
    double frameRate = 15.0; 
    capture >> frame; 
    VideoWriter* writer = NULL; 
    // FIXME: need to change this to an absolute path that exists on this system 
    string outputFile = "/tmp/test.mov"; 
    writer = new VideoWriter(outputFile, 
       CV_FOURCC('j','p','e','g'), 
       frameRate,Size(frame.cols,frame.rows)); 


     for (;;) { 
      capture >> frame; 
      if (frame.empty()) 
       continue; 
      imshow(window_name, frame); 
     writer->write(frame); 
      char key = (char)waitKey(5); //delay N millis, usually long enough to display and capture input 
      switch (key) { 
     case 'q': 
     case 'Q': 
     case 27: //escape key 
      if(writer != NULL) { 
     delete writer; 
      } 
      return 0; 
     case ' ': //Save an image 
      sprintf(filename,"filename%.3d.jpg",n++); 
      imwrite(filename,frame); 
      cout << "Saved " << filename << endl; 
      break; 
     default: 
      break; 
      } 
     } 
     return 0; 
    } 

} 

int main(int ac, char** av) { 

    if (ac != 2) { 
     help(av); 
     return 1; 
    } 
    std::string arg = av[1]; 
    VideoCapture capture(arg); //try to open string, this will attempt to open it as a video file 
    if (!capture.isOpened()) //if this fails, try to open as a video camera, through the use of an integer param 
     capture.open(atoi(arg.c_str())); 
    if (!capture.isOpened()) { 
     cerr << "Failed to open a video device or video file!\n" << endl; 
     help(av); 
     return 1; 
    } 
    return process(capture); 
} 
0

Después de leer la respuesta de Misha. Resolví este problema en Mac OS 10.9 Mavericks y XCode 5 reinstalando opencv usando Homebrew.

cerveza instalar OpenCV with-ffmpeg

+0

¿Qué códec o cuatrocc opción usaste? – JohnAllen

2

que tenía el mismo problema. Lo resolví utilizando el Codec RGB Planar.

outputVideo.open(PathName, CV_FOURCC('8','B','P','S'), myvideo.get(CV_CAP_PROP_FPS),CvSize(outputframe.size())); 

El tamaño de salida es importante, pero funciona sin instalar nada.

Cuestiones relacionadas