OpenCV: obtener el control deslizante para actualizar su posición durante la reproducción de video

He seleccionado ‘Learning OpenCV’ y he estado probando algunos de los ejemplos / ejercicios de código. En este fragmento de código, quiero que el control deslizante actualice su posición con cada cambio de cuadro de video, pero por alguna razón no funcionará (la imagen se congela con el siguiente código):

#include "cv.h" #include "highgui.h" int g_slider_position = 0; CvCapture* g_capture = NULL; void onTrackbarSlide(int pos) { cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos); } int main(int argc, char** argv) { cvNamedWindow("The Tom 'n Jerry Show", CV_WINDOW_AUTOSIZE); g_capture = cvCreateFileCapture(argv[1]); int frames = (int) cvGetCaptureProperty( g_capture, CV_CAP_PROP_FRAME_COUNT ); if (frames != 0) { cvCreateTrackbar( "Position", "The Tom 'n Jerry Show", &g_slider_position, frames, onTrackbarSlide ); } IplImage* frame; while (1) { frame = cvQueryFrame(g_capture); if (!frame) break; cvSetTrackbarPos( "Position", "The Tom 'n Jerry Show", ++g_slider_position ); cvShowImage("The Tom 'n Jerry Show", frame); char c = cvWaitKey(33); if (c == 27) break; } cvReleaseCapture(&g_capture); cvDestroyWindow("The Tom 'n Jerry Show"); return 0; } 

¿Alguna idea de cómo hacer que el control deslizante y el video funcionen según lo previsto?

 This is the actual working code // PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO #include  #include  int g_slider_position = 0; CvCapture* video_capture = NULL; void onTrackbarSlide(int current_frame) { current_frame = g_slider_position; cvSetCaptureProperty(video_capture,CV_CAP_PROP_POS_FRAMES,current_frame); } int main( int argc, char** argv ) { cvNamedWindow( "Video", CV_WINDOW_AUTOSIZE ); video_capture = cvCreateFileCapture( "Crowdy.avi"); int no_of_frames = (int) cvGetCaptureProperty(video_capture,CV_CAP_PROP_FRAME_COUNT); if( no_of_frames!= 0 ) { cvCreateTrackbar("Slider","Video",&g_slider_position,no_of_frames,onTrackbarSlide); } IplImage* frame; while(1) { frame = cvQueryFrame( video_capture ); if( !frame ) break; cvShowImage( "Video", frame ); cvSetTrackbarPos("Slider","Video",++g_slider_position); char c = cvWaitKey(33); if( c == 27 ) break; } cvReleaseCapture( &video_capture ); cvDestroyWindow( "Video" ); return(0); } 

Está incrementando g_slider_position dos veces en el código, por lo que se incrementará más allá de su límite (establecido en cvCreateTrackbar como frames ). Esto probablemente está causando que su imagen se congele.

Para arreglarlo, cambia esto.

  g_slider_position++; cvSetTrackbarPos( "Position", "The Tom 'n Jerry Show", ++g_slider_position ); 

a

  cvSetTrackbarPos( "Position", "The Tom 'n Jerry Show", ++g_slider_position ); 

Tomando en cuenta el código editado, verificaría que OpenCV esté leyendo correctamente la cantidad de cuadros de su archivo. Mire el Capítulo 2.3 de Aprendizaje de OpenCV, ejemplo 2.3 para un método de recuperación genérica de la cantidad de cuadros de su AVI (si eso es lo que está usando).

En su código anterior, si el número de cuadros es 0, la barra de seguimiento no se crea, pero el código aún ingresa en un bucle que intenta actualizar la posición de la barra de seguimiento (si encuentra un cuadro). Yo usaría esto en su lugar:

 if (frames != 0) { cvCreateTrackbar( "Position", "The Tom 'n Jerry Show", &g_slider_position, frames, onTrackbarSlide ); } else { exit(1); } 

Esto me parece un poco complicado. Utilicé la cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES) para recuperar el marco actual y lo utilicé para actualizar el control deslizante.

La función de callback se usa solo para cambiar la posición dentro de g_capture.

Así que la llamada de vuelta es:

 //Call back for slider bar void onTrackbarSlide(int pos) { cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos); } 

Y el bucle es:

 IplImage* frame; //Frame grabbed from video while(1) { frame = cvQueryFrame( g_capture ); if (!frame ) break; cvShowImage( "Example2", frame ); g_frame_count = (int) cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES); cvSetTrackbarPos("Position","Example2", g_frame_count); char c = cvWaitKey(33); if ( c == 27 ) break; } 

Donde las variables g_ son globales.

Puedes probar la solución de abajo.

cambia esto

 void onTrackbarSlide(int pos) { cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos); } 

a

 void onTrackbarSlide( int pos ) { if( pos > g_slider_position + 1 ) cvSetCaptureProperty( g_capture, CV_CAP_PROP_POS_FRAMES, pos); } 

y también cambiar esto

 cvSetTrackbarPos( "Position", "The Tom 'n Jerry Show", ++g_slider_position ); 

a

 cvSetTrackbarPos( "Position", "The Tom 'n Jerry Show", g_slider_position + 1 ); 

Hola tengo código simlar e hice lo siguiente:

 void onTrackbarSlide(int pos) { if(pos > g_lastPosition+1 || pos < g_lastPosition) cvSetCaptureProperty(g_capture,CV_CAP_PROP_POS_FRAMES,pos); g_lastPosition = pos; } 

.............

 while(1) { frame = cvQueryFrame( g_capture ); if( !frame ) break; cvShowImage( "Example3", frame ); cvSetTrackbarPos("Position", "Example3", g_slider_position+1); char c = cvWaitKey(33); if( c == 27 ) break; } 

Así que puedes agarrar la barra deslizante en cualquier dirección, espero que esto pueda ayudar.

OK, finalmente resolví este problema de actualizar el control deslizante y también, si desea mover el control deslizante, el video se actualizará, no hay problema de congelación de imagen ahora

 #include "stdafx.h" #include #include #include int g_slider_position = 0; CvCapture* g_capture = NULL; int count=0; //initiate a global counter void onTrackbarSlide( int pos ) {// if you are moving the slider for more than two frames then this loop will initiate to // to update the video if(pos>count+2 || pos 

ok ahora lo que he hecho es que he creado un contador global que se actualizará junto con los marcos

Ahora, cuando usamos el control deslizante con el mouse en una posición diferente, en la rutina onTrackbarSlider, el bucle if se iniciará y establecerá el video en la nueva posición.