Great, so now you can use OpenCV to create your own video player, which will not be much different from countless video players out there already. But we are interested in computer vision, and we want to do some of that. Many basic vision tasks involve the application of filters to a video stream. We will modify the program we already have to do a simple operation on every frame of the video as it plays.
One particularly simple operation is the smoothing of an image, which effectively reduces the information content of the
image by convolving it with a Gaussian or other similar kernel function. OpenCV makes such convolutions
exceptionally easy to do. We can start by creating a new window called "Example4-out"
,
where we can display the results of the processing. Then, after we have called cvShowImage()
to display the newly captured frame in the input
window, we can compute and display the smoothed image in the output window. See Example 2-4.
Example 2-4. Loading and then smoothing an image before it is displayed on the screen
#include "cv.h" #include "highgui.h" void example2_4( IplImage* image ) // Create some windows to show the input // and output images in. // cvNamedWindow( "Example4-in" ); cvNamedWindow( "Example4-out" ); // Create a window to show our input image // cvShowImage( "Example4-in", image ); // Create an image to hold the smoothed output // IplImage* out = cvCreateImage( cvGetSize(image), IPL_DEPTH_8U, 3 ); // Do the smoothing // cvSmooth( image, out, CV_GAUSSIAN, 3, 3 ); // Show the smoothed image in the output window // cvShowImage( "Example4-out", out ); // Be tidy // cvReleaseImage( &out ); // Wait for the user to hit a key, then clean up the windows // cvWaitKey( 0 ); cvDestroyWindow( "Example4-in" ); cvDestroyWindow( "Example4-out" ); }
The first call to cvShowImage()
is no different than
in our previous example. In the next call, we allocate another image structure. Previously
we relied on cvCreateFileCapture()
to allocate the new
frame for us. In fact, that routine actually allocated only one frame and then wrote over
that data each time a capture call was made (so it actually returned the same pointer every
time we called it). In this case, however, we want to allocate our own image structure to
which we can write our smoothed image. The first argument is a CvSize
structure, which we can conveniently create by calling cvGetSize(image);
this gives us the size of the existing
structure image
. The second argument tells us what kind
of data type is used for each channel on each pixel, and the last argument indicates the
number of channels. So this image is three channels (with 8 bits per channel) and is the
same size as image
.
The smoothing operation is itself just a single call to the OpenCV library: we
specify the input image, the output image, the smoothing method, and the parameters for the
smooth. In this case we are requesting a Gaussian smooth over a 3 × 3 area centered on each
pixel. It is actually allowed for the output to be the same as the input image, and this
would work more efficiently in our current application, but we avoided doing this because it
gave us a chance to introduce cvCreateImage()
!
Now we can show the image in our new second window and then free it: cvReleaseImage()
takes a pointer to the IplImage*
pointer and then de-allocates all of the memory associated with that image.