2010-06-04 15 views
18

He estado tratando de encontrar/implementar una función de búsqueda y rebobinado (para video (.avi)) usando OpenCV en C++, pero no puedo encontrar la manera de hacerlo, salvo pasar por el todo el archivo una vez y guardando cada imagen. ¿Hay alguna otra manera?OpenCV Seek Function/Rewind

Cualquier ayuda sería muy apreciada; Gracias de antemano!

+1

Por cierto, como punta, la búsqueda de OpenCV no funciona correctamente en flv si te quedas atascado cada vez que buscar no funcionó. Me llevó un día para resolverlo! –

Respuesta

37

Usando cvSetCaptureProperty() puede alternar entre fotogramas, ya sea en milisegundos o por número de fotograma ordinal.

int cvSetCaptureProperty(CvCapture* capture, int property_id, double value); 

property_id es una propiedad que tendría que utilizar. Puede ser uno de los siguientes:

  1. CV_CAP_PROP_POS_MSEC - posición en milisegundos desde el archivo comenzando
  2. CV_CAP_PROP_POS_FRAMES - posición en marcos
  3. CV_CAP_PROP_POS_AVI_RATIO - posición en unidades relativas (0 - inicio de la archivo, 1 - final del archivo)
  4. CV_CAP_PROP_FRAME_WIDTH - ancho de fotogramas de la secuencia de vídeo (sólo para cámaras)
  5. CV_CAP_PROP_FRAME_HEIGHT - hei lucha de fotogramas de la secuencia de vídeo (sólo para cámaras)
  6. CV_CAP_PROP_FPS - velocidad de cuadro (sólo para cámaras)
  7. CV_CAP_PROP_FOURCC - código de 4 caracteres de códec (sólo para cámaras).

Los dos primeros son de su interés.

EDIT: más información :)

Puede desplazarse a través de los marcos con sólo llamar repetidamente la función mencionada con diferentes índices de marco.

cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameIndex); 

Ejemplo:

IplImage* frame; 
CvCapture* capture = cvCreateFileCapture("test.avi"); 

/* iterate through first 10 frames */ 
for (int i = 0; i < 10; i++) 
{ 
    /* set pointer to frame index i */ 
    cvSetCaptureProperty(capture, CV_CAP_POS_FRAMES, i); 

    /* capture the frame and do sth with it */ 
    frame = cvQueryFrame(capture); 
} 

Se puede poner un código similar para ejecutar cada vez que el usuario hace clic en un botón para avanzar/retroceder el video.

El método C++ (OpenCV 2 y superior) sería utilizar este método en su lugar con el mismo property_id y valor.

bool VideoCapture::set(int property_id, double value) 
+0

¿Algún ejemplo? Digamos que si tengo un archivo .avi, ¿cómo lo usaría para recorrer los fotogramas? – Cenoc

+0

Gracias por el puntero por cierto. – Cenoc

+0

Editado mi respuesta. – Adi

0

En la biblioteca highgui encontrará funciones para una barra de búsqueda (cvCreateTrackbar y sus amigos).

+0

tal como se describe, no suena como una barra de búsqueda; suena como una barra de seguimiento regular. Además, cada ejemplo que encontré en línea, lo utilizó para otros shiz aleatorios, como cambiar el tono de la imagen. – Cenoc

+0

Puede enganchar la barra de seguimiento a cualquier variable/evento que desee, incluida la posición del archivo. Necesitas hacer un poco de trabajo emore que una barra de búsqueda integrada pero está ahí –

1

Creo que tendrías que leer todo el archivo en una matriz de IplImages, y luego trabajar en eso. La razón es que cvQueryFrame es un proceso unidireccional, lee un cuadro por vez en orden. No puedo pensar de otra manera. Dependiendo de la duración del video, el tiempo de inicialización puede no ser tan malo.

Las cvTrackbars son como dices, principalmente usadas para modificar parámetros. Alteran el valor de una variable (dado como un parámetro en forma de puntero) y lanzan una función de devolución de llamada. Desafortunadamente, son los únicos elementos de estilo de botón en HighGUI hasta donde sé

+0

Wow, muchas gracias. Adivina que eso lo reduce para mí; Pensé que ese podría ser el caso. Supongo que tengo que dejar de ser flojo y hacerlo. – Cenoc