Playing a video with OpenCV is almost as easy as displaying a single picture. Th e only newissue we face is that we need some kind of loop to read each frame in sequence; we mayalso need some way to get out of that loop if the movie is too boring.
#include "highgui.h"
int main( int argc, char** argv ) {
char *videoName="how-to-read-books. avi";
cvNamedWindow( "Play Video", CV_WINDOW_AUTOSIZE );
CvCapture* capture = cvCreateFileCapture( videoName );
IplImage* frame;
while(1) {
frame = cvQueryFrame( capture );
if( !frame ) break;
cvShowImage( "Play Video", frame );
char c = cvWaitKey(33);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow( "Play Video" );
}
Th e function cvCreateFileCapture() takes as its argument the name of the AVI fi le to be
loaded and then returns a pointer to a CvCapture structure. Th is structure contains all of
the information about the AVI fi le being read, including state information. When created
in this way, the CvCapture structure is initialized to the beginning of the AVI.
CvCapture* capture = cvCreateFileCapture( videoName );
Th e function cvCreateFileCapture() takes as its argument the name of the AVI fi le to be
loaded and then returns a pointer to a CvCapture structure. Th is structure contains all of
the information about the AVI fi le being read, including state information. When created
in this way, the CvCapture structure is initialized to the beginning of the AVI.
frame = cvQueryFrame( capture );
Once inside of the while(1) loop, we begin reading from the AVI fi le. cvQueryFrame()
takes as its argument a pointer to a CvCapture structure. It then grabs the next video
frame into memory (memory that is actually part of the CvCapture structure). A pointer
is returned to that frame. Unlike cvLoadImage, which actually allocates memory for the
image, cvQueryFrame uses memory already allocated in the CvCapture structure. Th us it
will not be necessary (or wise) to call cvReleaseImage() for this “frame” pointer. Instead,
the frame image memory will be freed when the CvCapture structure is released.
c = cvWaitKey(33);
if( c == 27 ) break;
Once we have displayed the frame, we then wait for 33 ms.* If the user hits a key, then c
will be set to the ASCII value of that key; if not, then it will be set to –1. If the user hits
the Esc key (ASCII 27), then we will exit the read loop. Otherwise, 33 ms will pass and
we will just execute the loop again.
It is worth noting that, in this simple example, we are not explicitly controlling
the speed of the video in any intelligent way. We are relying solely on the timer in
cvWaitKey() to pace the loading of frames. In a more sophisticated application it would
be wise to read the actual frame rate from the CvCapture structure (from the AVI) and
behave accordingly!
cvReleaseCapture( &capture );
When we have exited the read loop—because there was no more video data or because
the user hit the Esc key—we can free the memory associated with the CvCapture structure.
Th is will also close any open file handles to the AVI fi le.