Reading and Writing Videos using OpenCV (2023)

Reading and writing videos in OpenCV is very similar to reading and writing images. A video is nothing but a series of images that are often referred to as frames. So, all you need to do is loop over all the frames in a video sequence, and then process one frame at a time. In this post, we will demonstrate how to read, display and write videos from a file, an image sequence and a webcam. We will also look into some of the errors that might occur in the process, and help understand how to resolve them.

  • Reading videos
    • From a file
    • From Image-sequence
    • From a webcam
  • Writing videos
  • Errors That One Might Face when Reading or Writing Videos
  • Summary

Let’s go through the code example for reading a video file first.This essentially contains the functions for reading a video from disk and displaying it. As you proceed further, we will discuss the functions in detail used in this implementation.

Python

import cv2 # Create a video capture object, in this case we are reading the video from a filevid_capture = cv2.VideoCapture('Resources/Cars.mp4')if (vid_capture.isOpened() == False):print("Error opening the video file")# Read fps and frame countelse:# Get frame rate information# You can replace 5 with CAP_PROP_FPS as well, they are enumerationsfps = vid_capture.get(5)print('Frames per second : ', fps,'FPS')# Get frame count# You can replace 7 with CAP_PROP_FRAME_COUNT as well, they are enumerationsframe_count = vid_capture.get(7)print('Frame count : ', frame_count)while(vid_capture.isOpened()):# vid_capture.read() methods returns a tuple, first element is a bool # and the second is frameret, frame = vid_capture.read()if ret == True:cv2.imshow('Frame',frame)# 20 is in milliseconds, try to increase the value, say 50 and observekey = cv2.waitKey(20)if key == ord('q'):breakelse:break# Release the video capture objectvid_capture.release()cv2.destroyAllWindows()

C++

// Include Libraries#include<opencv2/opencv.hpp>#include<iostream>// Namespace to nullify use of cv::function(); syntaxusing namespace std;using namespace cv;int main(){// initialize a video capture objectVideoCapture vid_capture("Resources/Cars.mp4");// Print error message if the stream is invalidif (!vid_capture.isOpened()){cout << "Error opening video stream or file" << endl;}else{// Obtain fps and frame count by get() method and print// You can replace 5 with CAP_PROP_FPS as well, they are enumerationsint fps = vid_capture.get(5);cout << "Frames per second :" << fps;// Obtain frame_count using opencv built in frame count reading method// You can replace 7 with CAP_PROP_FRAME_COUNT as well, they are enumerationsint frame_count = vid_capture.get(7);cout << " Frame count :" << frame_count;}// Read the frames to the last framewhile (vid_capture.isOpened()){// Initialise frame matrixMat frame; // Initialize a boolean to check if frames are there or notbool isSuccess = vid_capture.read(frame);// If frames are present, show itif(isSuccess == true){//display framesimshow("Frame", frame);}// If frames are not there, close itif (isSuccess == false){cout << "Video camera is disconnected" << endl;break;}//wait 20 ms between successive frames and break the loop if key q is pressedint key = waitKey(20);if (key == 'q'){cout << "q key is pressed by the user. Stopping the video" << endl;break;}}// Release the video capture objectvid_capture.release();destroyAllWindows();return 0;}

I’ve partnered exclusively withOpenCV.orgto bring you official courses in AI, Computer Vision, and Deep Learning to take you on a structured path from first steps to mastery.

These are the main functions in OpenCV video I/O that we are going to discuss in this blog post:

  1. cv2.VideoCapture – Creates a video capture object, which would help stream or display the video.
  2. cv2.VideoWriter – Saves the output video to a directory.
  3. In addition, we also discuss other needed functions such as cv2.imshow(), cv2.waitKey() and the get() method which is used to read the video metadata such as frame height, width, fps etc.

In this example, you will be reading the above video (‘Cars.mp4’) and displaying it.

We assume you already have OpenCV in your system. If you need to install OpenCV, please visit the relevant link below.

  1. Install OpenCV on Windows
  2. Install OpenCV on MacOS
  3. Install OpenCV on Ubuntu

We have provided the codes both in Python and C++ languages for your study and practice.

Now let’s start with it.

First we import the OpenCV library. Please note that for C++, you would normally use cv::function(), but because we choose to use the cv namespace (using namespace cv), we can access the OpenCV functions directly, without pre-pending cv:: to the function name.

Python

# Import librariesimport cv2

Download CodeTo easily follow along this tutorial, please download code by clicking on the button below. It's FREE!

Download Code

C++

// Include Libraries#include<opencv2/opencv.hpp>#include<iostream>using namespace std;using namespace cv;

Reading Video From a File

The next code block below uses the VideoCapture() class to create a VideoCapture object, which we will then use to read the video file. The syntax for using this class is shown below:

VideoCapture(path, apiPreference)

The first argument is the filename/path to the video file. The second is an optional argument, indicating an API preference.Some of the options associated with this optional argument will be discussed further below. To learn more about apiPreference, visit the official documentation link VideoCaptureAPIs.

Python

# Create a video capture object, in this case we are reading the video from a filevid_capture = cv2.VideoCapture('Resources/Cars.mp4')

C++

# Create a video capture object, in this case we are reading the video from a fileVideoCapture vid_capture("Resources/Cars.mp4");

For all the examples given below, you can use the same video file that we have used here, which is available in the Downloadable Code folder, or you can use your own video file.


Now that we have a video capture object we can use the isOpened() method to confirm the video file was opened successfully. The isOpened() method returns a boolean that indicates whether or not the video stream is valid. Otherwise you will get an error message. The error message can imply many things. One of them is that the entire video is corrupted, or some frames are corrupted.Assuming the video file was opened successfully, we can use the get() method to retrieve important metadata associated with the video stream. Note that this method does not apply to web cameras. The get() method takes a single argument from an enumerated list of options documented here. In the example below, we provided the numeric values 5 and 7, which correspond to the frame rate (CAP_PROP_FPS) and frame count (CAP_PROP_FRAME_COUNT). The numeric value or the name can be supplied.

Python

if (vid_capture.isOpened() == False):print("Error opening the video file")else:# Get frame rate informationfps = int(vid_capture.get(5))print("Frame Rate : ",fps,"frames per second")# Get frame countframe_count = vid_capture.get(7)print("Frame count : ", frame_count)

C++

if (!vid_capture.isOpened()){cout << "Error opening video stream or file" << endl;}else{ // Obtain fps and frame count by get() method and printint fps = vid_capture.get(5):cout << "Frames per second :" << fps;frame_count = vid_capture.get(7);cout << "Frame count :" << frame_count;}

After retrieving the desired metadata associated with the video file, we are now ready to read each image frame from the file. This is accomplished by creating a loop and reading one frame at a time from the video stream using the vid_capture.read() method.

The vid_capture.read() method returns a tuple, where the first element is a boolean and the next element is the actual video frame. When the first element is True, it indicates the video stream contains a frame to read.

If there is a frame to read, you can then use imshow() to display the current frame in a window, otherwise exit the loop.Notice that you also use the waitKey() function to pause for 20ms between video frames. Calling the waitKey() function lets you monitor the keyboard for user input. In this case, for example, if the user presses the ‘q’ key, you exit the loop.

Python

while(vid_capture.isOpened()):# vCapture.read() methods returns a tuple, first element is a bool # and the second is frameret, frame = vid_capture.read()if ret == True:cv2.imshow('Frame',frame)k = cv2.waitKey(20)# 113 is ASCII code for q keyif k == 113:breakelse:break

C++

while (vid_capture.isOpened()){ // Initialize frame matrix Mat frame; // Initialize a boolean to check if frames are there or not bool isSuccess = vid_capture.read(frame); // If frames are present, show it if(isSuccess == true) { //display frames imshow("Frame", frame); } // If frames are not there, close it if (isSuccess == false) { cout << "Video camera is disconnected" << endl; break; } //wait 20 ms between successive frames and break the loop if key q is pressed int key = waitKey(20); if (key == 'q') { cout << "q key is pressed by the user. Stopping the video" << endl; break; } }

Once the video stream is fully processed or the user prematurely exits the loop, you release the video-capture object (vid_capture) and close the window, using the following code:

Python

# Release the objectsvid_capture.release()cv2.destroyAllWindows()

C++

// Release video capture objectvid_capture.release();destroyAllWindows();

Reading an Image Sequence

Processing image frames from an image sequence is very similar to processing frames from a video stream. Just specify the image files which are being read.

In the example below,

  • You continue using a video-capture object
  • But instead of specifying a video file, you simply specify an image sequence
    • Using the notation shown below (Cars%04d.jpg), where %04d indicates a four-digit sequence-naming convention (e.g. Cars0001.jpg, Cars0002.jpg, Cars0003.jpg, etc).
    • If you had specified “Race_Cars_%02d.jpg” then you would be looking for files of the form:

(Race_Cars_01.jpg, Race_Cars_02.jpg, Race_Cars_03.jpg, etc…).

All other codes described in the first example would be the same.

Python

vid_capture = cv2.VideoCapture('Resources/Image_sequence/Cars%04d.jpg')

C++

VideoCapture vid_capture("Resources/Image_sequence/Cars%04d.jpg");

Reading Video from a Webcam

Reading a video stream from a web camera is also very similar to the examples discussed above. How’s that possible? It’s all thanks to the flexibility of the video capture class in OpenCV, which has several overloaded functions for convenience that accept different input arguments. Rather than specifying a source location for a video file or an image sequence, you simply need to give a video capture device index, as shown below.

  • If your system has a built-in webcam, then the device index for the camera will be ‘0’.
  • If you have more than one camera connected to your system, then the device index associated with each additional camera is incremented (e.g. 1, 2, etc).

Python

vid_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)

C++

VideoCapture vid_capture(0);

You might be wondering about the flag CAP_DSHOW. This is an optional argument, and is therefore not required. CAP_DSHOW is just another video-capture API preference, which is short for directshow via video input.

Writing Videos

Let’s now take a look at how to write videos. Just like video reading, we can write videos originating from any source (a video file, an image sequence, or a webcam). To write a video file:

  • Retrieve the image frame height and width, using the get() method.
  • Initialize a video capture object (as discussed in the previous sections), to read the video stream into memory, using any of the sources previously described.
  • Create a video writer object.
  • Use the video writer object to save the video stream to disk.

Continuing with our running example, let’s start by using the get() method to obtain the video frame width and height.

Python

# Obtain frame size information using get() methodframe_width = int(vid_capture.get(3))frame_height = int(vid_capture.get(4))frame_size = (frame_width,frame_height)fps = 20

C++

// Obtain frame size information using get() methodInt frame_width = static_cast<int>(vid_capture.get(3));int frame_height = static_cast<int>(vid_capture.get(4));Size frame_size(frame_width, frame_height);int fps = 20;

As previously discussed, the get() method from the VideoCapture() class requires:

  • A single argument from an enumerated list that allows you to retrieve a variety of metadata associated with the video frames.

The metadata available is extensive, and can be found here.

  • In this case, you are retrieving the frame width and height, by specifying 3 (CAP_PROP_FRAME_WIDTH) and 4 (CAP_PROP_FRAME_HEIGHT). You will use these dimensions further below, when writing the video file to disk.

In order to write a video file, you need to first create a video-writer object from the VideoWriter() class, as shown in the code below.

Here’s the syntax for VideoWriter():

VideoWriter(filename, apiPreference, fourcc, fps, frameSize[, isColor])

The VideoWriter() class takes the following arguments:

  • filename: pathname for the output video file
  • apiPreference: API backends identifier
  • fourcc: 4-character code of codec, used to compress the frames (fourcc)
  • fps: Frame rate of the created video stream
  • frame_size: Size of the video frames
  • isColor: If not zero, the encoder will expect and encode color frames. Else it will work with grayscale frames (the flag is currently supported on Windows only).

The following code creates the video writer object, output from the VideoWriter() class. A special convenience function is used to retrieve the four-character codec, required as the second argument to the video writer object, cv2.

  • VideoWriter_fourcc('M', 'J', 'P', 'G') in Python.
  • VideoWriter::fourcc('M', 'J', 'P', 'G') in C++.

The video codec specifies how the video stream is compressed. It converts uncompressed video to a compressed format or vice versa. To create AVI or MP4 formats, use the following fourcc specifications:

AVI: cv2.VideoWriter_fourcc('M','J','P','G')

MP4: cv2.VideoWriter_fourcc(*'XVID')

The next two input arguments specify the frame rate in FPS, and the frame size (width, height).

Python

# Initialize video writer objectoutput = cv2.VideoWriter('Resources/output_video_from_file.avi', cv2.VideoWriter_fourcc('M','J','P','G'), 20, frame_size)

C++

//Initialize video writer objectVideoWriter output("Resources/output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'),frames_per_second, frame_size);

Now that you have created a video writer object, use it to write the video file to disk, one frame at a time, as shown in the code below. Here, you are writing an AVI video file to disk, at 20 frames per second. Note how we have simplified to loop from the previous examples.

Python

while(vid_capture.isOpened()): # vid_capture.read() methods returns a tuple, first element is a bool # and the second is frame ret, frame = vid_capture.read() if ret == True: # Write the frame to the output files output.write(frame) else: print(‘Stream disconnected’) break

C++

while (vid_capture.isOpened()){ // Initialize frame matrix Mat frame; // Initialize a boolean to check if frames are there or not bool isSuccess = vid_capture.read(frame); // If frames are not there, close it if (isSuccess == false) { cout << "Stream disconnected" << endl; break; } // If frames are present if(isSuccess == true) { //display frames output.write(frame); // display frames imshow("Frame", frame); // wait for 20 ms between successive frames and break // the loop if key q is pressed int key = waitKey(20); if (key == ‘q’) { cout << "Key q key is pressed by the user. Stopping the video" << endl; break; } } }

Finally, in the code below, release the video capture and video-writer objects.

Python

# Release the objectsvid_capture.release()output.release()

C++

// Release the objectsvid_capture.release();output.release();

Errors That One Might Face when Reading or Writing Videos

Video reading

While reading frames it can throw an error if the path is wrong or the file is corrupted or frame is missing.That’s why we are using an if statement inside the while loop. Which can be seen in the line, if ret == True. This way it will process it only when frames are present. Following is an example of an error log that is observed in this case. It is not the full log, only key parameters are included.

cap_gstreamer.cpp:890: error: (-2) GStreamer: unable to start pipeline in function

For wrong path:

When you provide a wrong path to a video, then it will not show any error or warning using the VideoCapture() class. The issues will arise when you will try to do any operation on the video frames. For this, you can use a simple if block for checking whether you have read a video file or not like we did in our example. That should print the following message.

Error opening the video file

Video writing

In this step various errors can occur. Most common are frame size error and api preference error. If the frame size is not similar to the video, then even though we get a video file at the output directory, it will be blank. If you are using the NumPy shape method to retrieve frame size, remember to reverse the output as OpenCV will return height x width x channels. If it is throwing an api preference error, we might need to pass the CAP_ANY flag in the VideoCapture() argument. It can be seen in the webcam example, where we are using CAP_DHOW to avoid warnings being generated.

Following are the examples of error logs:

When CAP_DSHOW is not passed:

[WARN:0]...cap_msmf.cpp(438) …. terminating async callback

When frame size is not correct:

cv2.error: OpenCV(4.5.2) :-1: error: (-5:Bad argument) in function 'VideoWriter'
> Overload resolution failed:
> - Can't parse 'frameSize'. Sequence item with index 0 has a wrong type
> - VideoWriter() missing required argument 'frameSize' (pos 5)
> - VideoWriter() missing required argument 'params' (pos 5)
> - VideoWriter() missing required argument 'frameSize' (pos 5)

Expand Your Knowledge

I’ve partnered exclusively withOpenCV.orgto bring you official courses in AI, Computer Vision, and Deep Learning to take you on a structured path from first steps to mastery.

Summary

In this blog, you learned to read and display video streams from three different sources, using a video-capture object. Even saw how to use a video-capture object to retrieve important metadata from the video stream. We also demonstrated how to write video streams to disk, using a video-writer object. You may also find it helpful to resize video frames, or annotate them with shapes and text. For this, just modify the individual image frames.

Now that you know how to read and write videos, and are comfortable using OpenCV,keep up the pace. And keep learning.

Subscribe & Download Code

Subscribe & Download Code

If you liked this article and would like to download code (C++ and Python) and example images used in this post, please click here. Alternately, sign up to receive a free Computer Vision Resource Guide. In our newsletter, we share OpenCV tutorials and examples written in C++/Python, and Computer Vision and Machine Learning algorithms and news.

Download Example Code

Top Articles
Latest Posts
Article information

Author: Patricia Veum II

Last Updated: 11/12/2022

Views: 5492

Rating: 4.3 / 5 (64 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Patricia Veum II

Birthday: 1994-12-16

Address: 2064 Little Summit, Goldieton, MS 97651-0862

Phone: +6873952696715

Job: Principal Officer

Hobby: Rafting, Cabaret, Candle making, Jigsaw puzzles, Inline skating, Magic, Graffiti

Introduction: My name is Patricia Veum II, I am a vast, combative, smiling, famous, inexpensive, zealous, sparkling person who loves writing and wants to share my knowledge and understanding with you.