In many applications we will want to record streaming input or even disparate captured
images to an output video stream, and OpenCV provides a straightforward method for doing this. Just
as we are able to create a capture device that allows us to grab frames one at a time from a
video stream, we are able to create a writer device that allows us to place frames one by
one into a video file. The routine that allows us to do this is cvCreateVideoWriter()
.
Once this call has been made, we may successively call cvWriteFrame()
, once for each frame, and finally cvReleaseVideoWriter()
when we are done. Example 2-10 describes a simple program that opens
a video file, reads the contents, converts them to a log-polar format (something like what
your eye actually sees, as described in Chapter 6), and writes out
the log-polar image to a new video file.
Example 2-10. A complete program to read in a color video and write out the log-polar transformed video
// Convert a video to grayscale // argv[1]: input video file // argv[2]: name of new output file // #include "cv.h" #include "highgui.h" main( int argc, char* argv[] ) { CvCapture* capture = 0; capture = cvCreateFileCapture( argv[1] ); if(!capture){ return -1; } IplImage *bgr_frame=cvQueryFrame(capture);//Init the video read double fps = cvGetCaptureProperty ( capture, CV_CAP_PROP_FPS ); CvSize size = cvSize( (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_WIDTH), (int)cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT) ); CvVideoWriter *writer = cvCreateVideoWriter( argv[2], CV_FOURCC('M','J','P','G'), fps, size ); IplImage* logpolar_frame = cvCreateImage( size, IPL_DEPTH_8U, 3 ); while( (bgr_frame=cvQueryFrame(capture)) != NULL ) { cvLogPolar( bgr_frame, logpolar_frame, cvPoint2D32f(bgr_frame->width/2, bgr_frame->height/2), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS ); cvWriteFrame( writer, logpolar_frame ); } cvReleaseVideoWriter( &writer ); cvReleaseImage( &logpolar_frame ); cvReleaseCapture( &capture ); return(0); }
Looking over this program reveals mostly familiar elements. We open one video; start
reading with cvQueryFrame()
, which is necessary to read
the video properties on some systems; and then use cvGetCaptureProperty()
to ascertain various important properties of the video
stream. We then open a video file for writing, convert the frame to log-polar format, and
write the frames to this new file one at a time until there are none left. Then we close
up.
The call to cvCreateVideoWriter()
contains several
parameters that we should understand. The first is just the filename for the new file. The
second is the video codec with which the video stream will be
compressed. There are countless such codecs in circulation, but whichever codec you choose must be available on your
machine (codecs are installed separately from OpenCV). In our case we choose the relatively
popular MJPG codec; this is indicated to OpenCV by using the macro
CV_FOURCC()
, which takes four characters as arguments.
These characters constitute the "four-character code" of the codec, and every codec has such
a code. The four-character code for motion jpeg is MJPG, so we specify
that as CV_FOURCC('M','J','P','G')
.
The next two arguments are the replay frame rate, and the size of the images we will be using. In our case, we set these to the values we got from the original (color) video.