martes, 30 de marzo de 2010

Compatibilidad Wxwidgets y OpenCV

Como primera propuesta en la linea del proyecto, sería utilizar las librerias de GUI elegidas (Wxwidgets), para desarrollar un interfaz, donde podamos mostrar un archivo de video manejado por las librerias de manejo de videos (OpenCV).

La primera aproximación del interfaz se tratara de un selector de archivo, una area para mostrar los frames del video reproducido, un conjunto de campos descriptores del video y un botón para reproducirlo. A continuación adjunto una captura de esta primera aproximación.



Para conseguir un funcionamiento correcto nos enfrentamos al primer problema. La incompatibilidad de estructuras de datos de ambas librerías.

Respecto a OpenCV y la reproducción del fichero de video, el algoritmo básico para reproducir un video sería inicializar la estructura CvCapture asociandole el fichero, recoger las propiedades del video que nos sean de utilidad, mediante la función cvGetCaptureProperty , especialmente los FPS, para mostrar los frames a una velocidad adecuada, y después ir recuperando los frames en orden (mediante cvQueryFrame()), hacer las tranformaciones necesarias si fuera necesario y mostrarlos en el lugar deseado. De forma sencilla sería algo como esto:

  1. int main( int argc, char** argv )
  2. {
  3. IplImage *frame;
  4. int key;

  5. /* supply the AVI file to play */
  6. assert( argc == 2 );

  7. /* load the AVI file */
  8. CvCapture *capture = cvCaptureFromAVI( argv[1] );

  9. /* always check */
  10. if( !capture ) return 1;

  11. /* get fps, needed to set the delay */
  12. int fps = ( int )cvGetCaptureProperty( capture,); CV_CAP_PROP_FPS

  13. /* display video */
  14. cvNamedWindow( "video", 0 );

  15. while( key != 'q' ) {
  16. /* get a frame */
  17. frame = cvQueryFrame( capture );

  18. /* always check */
  19. if( !frame ) break;

  20. /* display frame */
  21. cvShowImage( "video", frame );

  22. /* quit if user press 'q' */
  23. key = cvWaitKey( 1000 / fps );
  24. }

  25. /* free memory */
  26. cvReleaseCapture( &capture );
  27. cvDestroyWindow( "video" );

  28. return 0;
  29. }

Nuestro problema radica en que los frames se recogen en estructuras matriciales del tipo IplImage . Opencv brinda al usuario funciones básicas para la generación de GUI's básicas para hacer pruebas, recogidas en el módulo highgui , como por ejemplo cvShowImage(), que muestra un frame en una ventana básica.
En nuestro caso queremos mostrar frames en la GUI generada por wxwidgets. Las estructuras para mostrar imagenes mediante estas librerias son estructuras como wxImage o wxBitmap.

La solución consiste en recuperar la información de la estructura IplImage, en un array básico de bytes, mediante la función cvGetRawData
, y a partir de ahí crear una estructura de imagen genérica , independiente de plataforma, mediante el constructor de wxImage, a partir del array de bytes, para después convertirlo a un wxBitmap, que es representable en nuestra GUI.

No hay comentarios:

Publicar un comentario