Filter Images and Videos

The image filtering is a neighborhood operation in which the value of any given pixel in the output image is determined by applying a certain algorithm to the pixel values ​​in the vicinity of the corresponding input pixel. This technique is commonly used to smooth, sharpen and detect edges of images and videos.

Let's learn the meaning of some terms used when discussing image filtering techniques, kernel and convolution.


Kernel


Kernel is a matrix with an odd height and an odd width. It is also known as convolution matrix, mask or filter. Kernels are named based on their value distribution. Kernel is used to define a neighborhood of a pixel in a image filtering operation. Some of the popular kernels are Normalized box filter, Gaussian kernel, Laplacian kernel, edge detecting kernels etc. Kernels can be defined with different sizes. But large kernels result in a large processing time.

This is a 3 x 3 Normalized Box filter. This kernel is used in homogeneous smoothing (blurring).


This is a 5 x 5 Normalized Box filter. This kernel is also used in the homogeneous smoothing. In the same way, you can create a Normalized Box filter with any size to be used in the homogeneous smoothing .


This is a 3 x 3 Gaussian kernel used in Gaussian smoothing (blurring). 


This is a 5 x 5 Gaussian kernel used in Gaussian smoothing (blurring). In the same way, you may create a Gaussian kernel with any size. The value distribution of the kernel should be calculated using the 2-D Gaussian function.
2-D Gaussian Function
2-D Gaussian Function
x, y is the coordinates of the kernel where the origin is placed at the center. (i.e.  x = 0 and y = 0 at the center element of the kernel.) σ is the standard deviation of the Gaussian distribution. For larger standard deviations, larger kernels are required in order to accurately perform the Gaussian smoothing. The standard deviation of the following 5 x 5 Gaussian kernel is 1.

Convolution


Convolution is a mathematical operation performed on images by sliding a kernel across the whole image and calculating new values for each pixels based on the value of the kernel and the value of overlapping pixels of original image.

Convolution


C22 = (K11 x A11 + K12 x A12 + K13 x A13) + (K21 x A21 + K22 x A22 + K23 x A23) + (K31 x A31 + K32 x A32 + K33 x A33)
C23 = (K11 x A12 + K12 x A13 + K13 x A14) + (K21 x A22 + K22 x A23 + K23 x A24) + (K31 x A32 + K32 x A33 + K33 x A34)
C24 = (K11 x A13 + K12 x A14 + K13 x A15) + (K21 x A23 + K22 x A24 + K23 x A25) + (K31 x A33 + K32 x A34 + K33 x A35)

C32 = (K11 x A21 + K12 x A22 + K13 x A23) + (K21 x A31 + K22 x A32 + K23 x A33) + (K31 x A41 + K32 x A42 + K33 x A43)
C33 = (K11 x A22 + K12 x A23 + K13 x A24) + (K21 x A32 + K22 x A33 + K23 x A34) + (K31 x A42 + K32 x A43 + K33 x A44)



In the same way C34, can be calculated in the convolved image. But other values in the boundary of the convolved image (e.g C11, C12, etc) cannot be calculated in the same way because the kernel is partially overlapped with the original image at the boundary. Therefore non-overlapped non-existing pixel values should be calculated in order to determine the pixel values at the boundaries of the convolved image. There are various techniques to handle this boundary values, but I'm not going to discuss it in this tutorial.




After learning bit of theory of image filtering, let's learn some use cases of image filtering techniques with OpenCV C++ examples.



  • Smooth / Blur Images 

When an image is acquired by a camera or other method, the image may be corrupted by random dots and noises. Smoothing/blurring is one of image processing techniques to eliminate such imperfections and improve the image. Image smoothing techniques can be applied even for each frames of a video to eliminate imperfections and improve the video.

Invert Images and Videos

Here is the original image which I am going to filter using above methods.


Inverting an image is like taking the negative of an image.

///////////////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <cv.h>
#include <highgui.h>

int main()
{
        //display the original image
        IplImage* img = cvLoadImage("C:/MyPic.jpg");
        cvNamedWindow("MyWindow");
        cvShowImage("MyWindow", img);

        //invert and display the inverted image
        cvNot(img, img);
        cvNamedWindow("Inverted");
        cvShowImage("Inverted", img);

        cvWaitKey(0);
      
        //cleaning up
        cvDestroyWindow("MyWindow");
        cvDestroyWindow("Inverted");
        cvReleaseImage(&img);
      
        return 0;
}

///////////////////////////////////////////////////////////////////////////////////////

You can download this OpenCV visual c++ project from here

Inverted Image

 New OpenCV functions which are not found earlier are explained here
  • cvNot(img, img)
This function inverts every bit in every element of the image in the 1st parameter and places the result in the image in the 2nd parameter.
This function can process images in place. That means same variable can be used for the 1st and 2nd parameters.

e.g - For a 8 bit image, the value 0 will be mapped to (255-0)=255
                                        the value 46 will be mapped to (255-46)=209

        For a 16 bit image, the value 0 will be mapped to (65535-0)=65535
                                   the value 46 will be mapped to (65535-46)=65489


Dilate Images and Videos

Here is the original image which I am going to filter using above methods.

Dilating is something like opposite of the eroding an image. Here is the OpenCV code.

///////////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>

int main()
{
        //display the original image
        IplImage* img = cvLoadImage("C:/MyPic.jpg");
        cvNamedWindow("MyWindow");
        cvShowImage("MyWindow", img);

        //dilate and display the dilated image
        cvDilate(img, img, 0, 2);
        cvNamedWindow("Dilated");
        cvShowImage("Dilated", img);

        cvWaitKey(0);
       
        //cleaning up
        cvDestroyWindow("MyWindow");
        cvDestroyWindow("Dilated");
        cvReleaseImage(&img);
       
        return 0;
}

///////////////////////////////////////////////////////////////////////////////////////

You can download this OpenCV visual c++ project from here

Dilated Image

New OpenCV functions which are not found earlier are explained here
  • cvDilate(img, img, 0, 2)
The 1st parameter is the source image.
The 2nd parameter is the destination image which is to be the dilated image.
Here the 3rd parameter is the structuring element used for dilation. If it is 0, a 3×3 rectangular structuring element is used. 
The 4th parameter is the number of times, dilation is applied.
This function can process images in place. That means same variable can be used for the 1st and 2nd parameters.

Erode Images and Videos

Erosion is a fundamental morphological operation in image processing. As the name implies, this operation erodes foreground pixels in an image at their boundaries. After this erosion operation is performed, objects in an image becomes smaller where as the holes within the object (if any) becomes larger.

In this technique, each pixel value of the resultant image is calculated as the minimum value of the neighborhood of the pixel defined by the kernel. For color images, each color plane is processed independently.

3 x 3 kernel used in the erosion operation

3 x 3 kernel for erosion operation
3 x 3 kernel for erosion operation



Following image shows how to erode an image with the above 3 x 3 kernel. In the same way you can erode an image with 5 x 5, 7 x 7 and etc kernels.
Erode Image with 3 x 3 Kernel


Erode image with OpenCV


OpenCV has an in-built function to erode an image specifying the kernel size. Here is a simple program demonstrating how to erode an image with a 3 x 3 and 5 x 5 kernel with OpenCV.

//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
    // Read the image file
    Mat image = imread("D:/My OpenCV Website/Lotus.jpeg");

    // Check for failure
    if (image.empty())
    {
        cout << "Could not open or find the image" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    //Erode the image with 3x3 kernel
    Mat image_eroded_with_3x3_kernel;
    erode(image, image_eroded_with_3x3_kernel, getStructuringElement(MORPH_RECT, Size(3, 3)));

    //Erode the image with 5x5 kernel
    Mat image_eroded_with_5x5_kernel;
    erode(image, image_eroded_with_5x5_kernel, getStructuringElement(MORPH_RECT, Size(5, 5)));

    //Define names of the windows
    String window_name = "Lotus";
    String window_name_eroded_with_3x3_kernel = "Lotus eroded with 3 x 3 kernel";
    String window_name_eroded_with_5x5_kernel = "Lotus eroded with 5 x 5 kernel";

    // Create windows with above names
    namedWindow(window_name);
    namedWindow(window_name_eroded_with_3x3_kernel);
    namedWindow(window_name_eroded_with_5x5_kernel);

    // Show our images inside the created windows.
    imshow(window_name, image);
    imshow(window_name_eroded_with_3x3_kernel, image_eroded_with_3x3_kernel);
    imshow(window_name_eroded_with_5x5_kernel, image_eroded_with_5x5_kernel);

    waitKey(0); // Wait for any keystroke in the window

    destroyAllWindows(); //destroy all opened windows

    return 0;
}


Copy and paste the above code snippet into your IDE and run it. Please note that you have to replace "D:/My OpenCV Website/Lotus.jpeg" in the code with a valid location to an image in your computer. Then you should see set of images like the below.

Original Image
Original Image

Image eroded with 3 x 3 kernel
Image eroded with 3 x 3 kernel

Image eroded with 5 x 5 kernel
Image eroded with 5 x 5 kernel


Explanation


Let's go through the above OpenCV program line by line.

// Read the image file
Mat image = imread("D:/My OpenCV Website/Lotus.jpeg");

// Check for failure
if (image.empty())
{
    cout << "Could not open or find the image" << endl;
    cin.get(); //wait for any key press
    return -1;
}

This code segment loads an image from the file "D:/My OpenCV Website/Lotus.jpeg" and returns it as a Mat object. If the returned Mat object is empty, exit the program by returning from the main function. This is an important validation because calling imshow() on empty Mat object might crash your program.

//Erode the image with 3x3 kernel
Mat image_eroded_with_3x3_kernel;
erode(image, image_eroded_with_3x3_kernel, getStructuringElement(MORPH_RECT, Size(3, 3)));

erode() function erodes the image using the specified kernel which determines the neighborhood of a pixel over which the minimum is taken. getStructuringElement(MORPH_RECT, Size(3, 3)) function is used to get the rectangular kernel with the size of 3 x 3 for this morphological operation. The resultant image is stored in the image_eroded_with_3x3_kernel. If the image contains more than one channel (color image has 3 or 4 channels), each channel is processed independently.


//Erode the image with 5x5 kernel
Mat image_eroded_with_5x5_kernel;
erode(image, image_eroded_with_5x5_kernel, getStructuringElement(MORPH_RECT, Size(5, 5)));

erode() function erodes the image using the specified kernel which determines the neighborhood of a pixel over which the minimum is taken. getStructuringElement(MORPH_RECT, Size(5, 5)) function is used to get the rectangular kernel with the size of 5 x 5 for this morphological operation. The resultant image is stored in the image_eroded_with_5x5_kernel. If the image contains more than one channel (color image has 3 or 4 channels), each channel is processed independently.


//Define names of the windows
String window_name = "Lotus";
String window_name_eroded_with_3x3_kernel = "Lotus eroded with 3 x 3 kernel";
String window_name_eroded_with_5x5_kernel = "Lotus eroded with 5 x 5 kernel";

// Create windows with above names
namedWindow(window_name);
namedWindow(window_name_eroded_with_3x3_kernel);
namedWindow(window_name_eroded_with_5x5_kernel);

// Show our images inside the created windows.
imshow(window_name, image);
imshow(window_name_eroded_with_3x3_kernel, image_eroded_with_3x3_kernel);
imshow(window_name_eroded_with_5x5_kernel, image_eroded_with_5x5_kernel);

The above code segment creates windows and shows images in them.

waitKey(0); // Wait for any keystroke in the window

destroyAllWindows(); //destroy all opened windows

The program waits for any keystroke. After any key is pressed, all opened windows will be destroyed.

Summary


In the above section, you have learned,

  • How to load an image from a file
  • How to perform the erode morphological operation on images with a given filter.
  • How to create windows and display images
  • How to wait without exiting the program until the user presses a key
  • How to destroy created windows




Erode video with OpenCV



Now I am going to show you how to perform erode morphological operation on a video using an OpenCV C++ example. This is pretty much similar to the previous example. It is recommended to go through the Play Video from File or Camera first in order to understand the following example better.

//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    //open the video file for reading
    VideoCapture cap("D:/My OpenCV Website/A Herd of Deer Running.mp4");

    // if not success, exit program
    if (cap.isOpened() == false)
    {
        cout << "Cannot open the video file" << endl;
        cin.get(); //wait for any key press
        return -1;
    }



    //Define names of the window
    String window_name_of_original_video = "Original Video";
    String window_name_of_video_eroded_with_5x5_kernel = "Video eroded with 5 x 5 kernel";

    // Create a window with above names
    namedWindow(window_name_of_original_video, WINDOW_NORMAL);
    namedWindow(window_name_of_video_eroded_with_5x5_kernel, WINDOW_NORMAL);

    while (true)
    {
        Mat frame;
        bool bSuccess = cap.read(frame); // read a new frame from video 
        if (bSuccess == false)
        {
            cout << "Found the end of the video" << endl;
            break;
        }

        //erode the frame with 5x5 kernel
        Mat frame_eroded_with_5x5_kernel;
        erode(frame, frame_eroded_with_5x5_kernel, getStructuringElement(MORPH_RECT, Size(5, 5)));

        //show the frames in the created windows
        imshow(window_name_of_original_video, frame);
        imshow(window_name_of_video_eroded_with_5x5_kernel, frame_eroded_with_5x5_kernel);

        //wait for for 10 ms until any key is pressed.  
        //If the 'Esc' key is pressed, break the while loop.
        //If the any other key is pressed, continue the loop 
        //If any key is not pressed withing 10 ms, continue the loop
        if (waitKey(10) == 27)
        {
            cout << "Esc key is pressed by user. Stoppig the video" << endl;
            break;
        }
    }

    return 0;

}

Copy and paste the above code snippet into your IDE and run it. Please note that you have to replace "D:/My OpenCV Website/A Herd of Deer Running.mp4" in the code with a valid location to a video in your computer. Then you should see an eroded video along with the original video.

Save Images & Videos to File

In many real world computer vision applications, it is required to persist images and videos for future reference. Most common persisting method is to save the image or the video to a file. Therefore this tutorial is prepared to explain how to save images and videos to a file with OpenCV C++.

To understand this tutorial better,  please refer to Load & Display Image and Play Video from File or Camera first.


Save an Image to a File


In this section, you may learn how to save an image loaded from a file. In the same way, you can save images taken from a camera or any other methods.

//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
 // Read the image file
 Mat image = imread("D:/My OpenCV Website/fly-agaric.jpg");

 // Check for failure
 if (image.empty())
 {
  cout << "Could not open or find the image" << endl;
  cin.get(); //wait for any key press
  return -1;
 }

 /*
 Make changes to the image as necessary
 e.g.  
  1. Change brightness/contrast of the image
  2. Smooth/Blur image
  3. Crop the image
  4. Rotate the image
  5. Draw shapes on the image
 */

 bool isSuccess = imwrite("D:/MyImage.jpg", image); //write the image to a file as JPEG 
 //bool isSuccess = imwrite("D:/MyImage.png", image); //write the image to a file as PNG
 if (isSuccess == false)
 {
  cout << "Failed to save the image" << endl;
  cin.get(); //wait for a key press
  return -1;
 }

 cout << "Image is succusfully saved to a file" << endl;

 String windowName = "The Saved Image"; //Name of the window
 namedWindow(windowName); // Create a window
 imshow(windowName, image); // Show our image inside the created window.

 waitKey(0); // Wait for any keystroke in the window

 destroyWindow(windowName); //destroy the created window

 return 0;
}
Copy and paste above code snippet into your IDE and run it. Please note that you have to replace "D:/My OpenCV Website/fly-agaric.jpg" in the code with a valid location to an image in your computer. Then your image should be saved in the specified location.


Explanation


Let's go through the above code line by line.

// Read the image file
Mat image = imread("D:/My OpenCV Website/fly-agaric.jpg");

// Check for failure
if (image.empty())
{
 cout << "Could not open or find the image" << endl;
 cin.get(); //wait for any key press
 return -1;
}
These lines of code read the image from the specified file. If the image cannot be loaded, program will exit.

More details about each OpenCV functions in the above code segment can be found in Load & Display Image.


bool isSuccess = imwrite("D:/MyImage.jpg", image); //write the image to a file as JPEG 
//bool isSuccess = imwrite("D:/MyImage.png", image); //write the image to a file as PNG
if (isSuccess == false)
{
 cout << "Failed to save the image" << endl;
 cin.get(); //wait for a key press
 return -1;
}

cout << "Image is succusfully saved to a file" << endl;
The above code segment writes the given image to the specified file. If it is failed to write the image to the file, program will exit.


bool imwrite( const String& filename, InputArray img, const std::vector& params = std::vector())

This function writes the given img object to the specified file. On success, this function will return true, otherwise it will return false.

  1. filename - File name of the output image. Please note that the extension of the filename will be used to determine to the image format. (e.g. - If the filename is MyImage.jpg, a JPEG image will be written. If the filename is MyImage.png, a PNG image will be written.). jpeg, jpg, bmp, png, tiff and tif extensions are always supported. Other image file types are supported depending on your platform and installed codecs.

  2. img - The image object to be saved. Please note that this image object should have following properties. 
      • The bit depth of the image object should be 8 bit signed or 16 bit unsigned.
      • Number of channels of the image should be 1 or 3. For 3 channel image objects, BGR channel order should be present. 
    If the bit depth or the channel order of your image object is different from the above specification, you may use Mat::convertTo and cv::cvtColor functions to convert your image.

  3. params - This is an optional parameter.



String windowName = "The Saved Image"; //Name of the window
namedWindow(windowName); // Create a window
imshow(windowName, image); // Show our image inside the created window.

waitKey(0); // Wait for any keystroke in the window

destroyWindow(windowName); //destroy the created window
These lines of code create  a new window and display the image in it. The program will display the image in the window until any key is pressed. After a key is pressed, the window will be destroyed.

More details about each OpenCV functions in the above code segment can be found in Load & Display Image.


Summary


In the above section, you have learnt how to
  • Load an image from a file.
  • The loaded image can be modified as you wish. But it is not explained in this tutorial as it has been explained in other tutorials. (e.g. - Filtering Images, Rotate Image & Video, etc)
  • Save the image to a file
  • Display the image in a window



Save a Video to a File


In this section, you may learn how to save a video captured by a webcam to a file. In the same way, you can save a video file after doing any modifications.

//Uncomment the following line if you are compiling this code in Visual Studio
//#include "stdafx.h"

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char* argv[])
{
    //Open the default video camera
    VideoCapture cap(0);

    // if not success, exit program
    if (cap.isOpened() == false)
    {
        cout << "Cannot open the video camera" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    int frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH)); //get the width of frames of the video
    int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT)); //get the height of frames of the video
    
    Size frame_size(frame_width, frame_height);
    int frames_per_second = 10;

    //Create and initialize the VideoWriter object 
    VideoWriter oVideoWriter("D:/MyVideo.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 
                                                               frames_per_second, frame_size, true); 
    
    //If the VideoWriter object is not initialized successfully, exit the program
    if (oVideoWriter.isOpened() == false) 
    {
        cout << "Cannot save the video to a file" << endl;
        cin.get(); //wait for any key press
        return -1;
    }

    string window_name = "My Camera Feed";
    namedWindow(window_name); //create a window called "My Camera Feed"

    while (true)
    {
        Mat frame;
        bool isSuccess = cap.read(frame); // read a new frame from the video camera

        //Breaking the while loop if frames cannot be read from the camera
        if (isSuccess == false)
        {
            cout << "Video camera is disconnected" << endl;
            cin.get(); //Wait for any key press
            break;
        }

        /*
        Make changes to the frame as necessary
        e.g.  
         1. Change brightness/contrast of the image
         2. Smooth/Blur image
         3. Crop the image
         4. Rotate the image
         5. Draw shapes on the image
        */

        //write the video frame to the file
        oVideoWriter.write(frame); 

        //show the frame in the created window
        imshow(window_name, frame);

        //Wait for for 10 milliseconds until any key is pressed.  
        //If the 'Esc' key is pressed, break the while loop.
        //If any other key is pressed, continue the loop 
        //If any key is not pressed within 10 milliseconds, continue the loop 
        if (waitKey(10) == 27)
        {
            cout << "Esc key is pressed by the user. Stopping the video" << endl;
            break;
        }
    }

    //Flush and close the video file
    oVideoWriter.release();
    
    return 0;
}
Copy and paste the above code snippet into your IDE and run it. Then you should see the output of the webcam in the created window. After the 'Esc' key is pressed, the created window will be destroyed and the video output of the webcam will be saved in the given location.


Explanation


Let's go through the above code line by line.

//Open the default video camera
VideoCapture cap(0);

// if not success, exit program
if (cap.isOpened() == false)
{
    cout << "Cannot open the video camera" << endl;
    cin.get(); //wait for any key press
    return -1;
}
The above code segment opens the default webcam connected to your computer. If it is failed to open the camera, the program will exit. More details about each OpenCV functions in the above code segment can be found in Play Video from File or Camera.


int frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH)); //get the width of frames of the video
int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT)); //get the height of frames of the video

Size frame_size(frame_width, frame_height);
int frames_per_second = 10;

//Create and initialize the VideoWriter object 
VideoWriter oVideoWriter("D:/MyVideo.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), 
                                                           frames_per_second, frame_size, true); 

//If the VideoWriter object is not initialized successfully, exit the program                                                    
if (oVideoWriter.isOpened() == false) 
{
    cout << "Cannot save the video to a file" << endl;
    cin.get(); //wait for any key press
    return -1;
}
This code segment obtains the width and the height of the video frames of the webcam. Using the obtained information, the VideoWriter object is constructed and initialized. If the initialization is failed, the program will exit.


VideoWriter(const String& filename, int fourcc, double fps, Size frameSize, bool isColor = true)
This is one of the available overloaded constructors of the VideoWriter object. It constructs and initializes the VideoWriter object in order to write video frames to a given file.

  1. filename - Name of the file to write video frames.

  2. fourcc - 4-character code of the codec which is used to compress the video. The complete list of codes can be found in this page. But most of the codecs listed in this page might not work in your computer. These are some popular codecs which might work for you.
    • VideoWriter::fourcc('P', 'I', 'M', '1') for MPEG-1
    • VideoWriter::fourcc('M', 'J', 'P', 'G') for Motion JPEG
    • VideoWriter::fourcc('M', 'P', '4', '2') for MPEG-4 variation of Microsoft

  3. fps - Frames per second of the written video stream.

  4. frameSize - Size of the video frames written to this video stream

  5. isColor - Always pass true to this argument


while (true)
{
    Mat frame;
    bool isSuccess = cap.read(frame); // read a new frame from the video camera 

    //Breaking the while loop if frames cannot be read from the camera
    if (isSuccess == false)
    {
        cout << "Video camera is disconnected" << endl;
        cin.get(); //Wait for any key press
        break;
    }

    /*
    Make changes to the frame as necessary
    e.g.  
     1. Change brightness/contrast of the image
     2. Smooth/Blur image
     3. Crop the image
     4. Rotate the image
     5. Draw shapes on the image
    */

    //write the video frame to the file
    oVideoWriter.write(frame); 

    //show the frame in the created window
    imshow(window_name, frame);

    //Wait for for 10 milliseconds until any key is pressed.  
    //If the 'Esc' key is pressed, break the while loop.
    //If any other key is pressed, continue the loop 
    //If any key is not pressed within 10 milliseconds, continue the loop 
    if (waitKey(10) == 27)
    {
        cout << "Esc key is pressed by the user. Stopping the video" << endl;
        break;
    }
}
In each iteration of the above while loop, the program performs following tasks.
  • Read a frame from the camera.
  • Write the frame to the file.
  • Display the frame in a window.
The while loop will break if the Esc key is pressed or the program fails to read a frame from the camera.

void write(const Mat& image)
Write the frame to the file. The size of the frame should be same as the size you specified during the initialization of the VideoWriter object.


//Flush and close the video file
oVideoWriter.release();
This function flushes and closes the video file. This function is also executed within the destructor the the VideoWriter object.


Summary


In this section, you have learnt how to 
  • Open the camera
  • Initialize the VideoWriter object
  • Read frames from the camera
  • Write frames to a file
  • Flush and close the video file