I've picked up 'Learning OpenCV' and have been trying some of the code examples/exercises. In this code snippet, I want to get the slider to update its position with each video frame change, but for some reason it won't work (the picture freezes with the following code):
#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;
}
Any idea how to get the slider and video to work as intended?
This is the actual working code
// PROGRAM TO ADD A UPDATING TRACKBAR TO A VIDEO
#include <cv.h>
#include <highgui.h>
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);
}
You are incrementing g_slider_position twice in the code, so it will increment beyond its limit (set in cvCreateTrackbar
as frames
). This is likely causing your picture to freeze.
To fix, change this
g_slider_position++;
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
to
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
Accounting for the edited code, I would check that OpenCV is properly reading the number of frames from your file. Look at Learning OpenCV's Chapter 2, example 2.3 for a method of generically retrieving the number of frames from your AVI (if that is what you are using).
In your code above, if the number of frames is 0, the trackbar is not created but the code still enters a loop that attempts to update the trackbar position (if it finds a frame). I would use this instead:
if (frames != 0)
{
cvCreateTrackbar(
"Position",
"The Tom 'n Jerry Show",
&g_slider_position,
frames,
onTrackbarSlide
);
}
else
{
exit(1);
}
This seems a bit complicated to me. I used the cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES)
call to retrieve the current frame and used this to update the slider.
The callback function is then used just to change the position within g_capture.
So the call back is:
//Call back for slider bar
void onTrackbarSlide(int pos) {
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}
And the loop is:
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;
}
Where the g_
variables are global.
You can try the solution below.
change this
void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);
}
to
void onTrackbarSlide( int pos )
{
if( pos > g_slider_position + 1 )
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos);
}
and also change this
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
++g_slider_position
);
to
cvSetTrackbarPos(
"Position",
"The Tom 'n Jerry Show",
g_slider_position + 1
);
Hi I have simlar code and I did the following:
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;
}
So you can grab the slide bar to any direction , I hope this can help
OK I finally solved this problem of updating the slider and also if you want to move the slider the video will update there is no problem of picture freezing now
#include "stdafx.h"
#include<cv.h>
#include<cxcore.h>
#include<highgui.h>
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<count-2){
cvSetCaptureProperty(
g_capture,
CV_CAP_PROP_POS_FRAMES,
pos);}
count=pos;
}
int main(int argc, _TCHAR* argv[])
{
//int count=0;
cvNamedWindow("Example3",CV_WINDOW_AUTOSIZE);
g_capture=cvCreateFileCapture("video.avi");
int frames = (int) cvGetCaptureProperty(
g_capture,
CV_CAP_PROP_FRAME_COUNT
);
if(frames!= 0) {
cvCreateTrackbar(
"Position",
"Example3",
&g_slider_position,
frames,
onTrackbarSlide
);
}
IplImage* frame;
while (1)
{
count++; // the counter will move along with the frame
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;
}
cvReleaseCapture(&g_capture);
cvDestroyWindow("Example3");
return 0;
}
ok now what i have done is that i have created a global counter which will be updated alongside with the frames
now when we use the slider with the mouse to a different position then in onTrackbarSlider routine the if loop will be initiated and it will set the video to the new position
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With