Count the total number of frames in a video with OpenCV and Python

count_frames_trailer_capture

Today’s blog post is part of a two part series on working with video files using OpenCV and Python.

The first part of this series will focus on a question emailed in by PyImageSearch reader, Alex.

Alex asks:

I need to count the total number of frames in a video file with OpenCV. The only way I’ve found to do this is to loop over each frame in the video file individually and increment a counter. Is there a faster way?

Great question Alex.

And rest assured, you’re not the first person who has asked me this question.

In the remainder of this blog post I’ll show you how to define a function that can quickly determine the total number of frames in a video file.

Next week we’ll use this function to aid us in a fun visualization task where I’ll demonstrate how to create “movie barcodes”. In order to generate these movie barcodes we’ll first need to know how many frames there are in our input movie file.

To learn more about fast, efficient frame counting with OpenCV and Python, just keep reading.

Looking for the source code to this post?
Jump right to the downloads section.

Count the total number of frames in a video with OpenCV and Python

There are two methods to determine the total number of frames in a video file using OpenCV and Python:

  1. Method #1: The fast, efficient way using the built-in properties OpenCV provides us to access the video file meta information and return the total number of frames.
  2. Method #2: The slow, inefficient technique that requires us to manually loop over each frame and increment a counter for each frame we’ve read.

Method #1 is obviously ideal.

All we need to do is open a pointer to the video file, tell OpenCV which meta property we are interested, and get the returned value.

No looping over frames manually.

No wasted CPU cycles decoding frames.

…however, I’m sure you’ve realized there is a catch.

The problem here is that Method #1 is buggy as all hell based on your OpenCV version and video codecs installed.

You’ll find there are situations where more than half of the .get  and .set  methods on video pointers simply don’t work. In situations like these we’ll inevitably have to revert to Method #2.

So, is there a way to encapsulate both of these methods into a single function?

You bet there is.

I’ve already implemented the count_frames function inside the imutils library, but to ensure you’re understanding what’s going on under the hood we’ll be reviewing the entire function here today.

The easy way to count frames with OpenCV and Python

The first method to count video frames in OpenCV with Python is very fast — it simply uses the built-in properties OpenCV provides to access a video file and read the meta information of the video.

Let’s go ahead and see how this function is implemented inside imutils now:

To start, we import our necessary Python packages on Lines 2 and 3. We’ll need the is_cv3  function to check which version of OpenCV we’re using along with cv2  for our actual OpenCV bindings.

We define the count_frames  function on Line 5. This method requires a single argument followed by a second optional one:

  • path : This is the path to where our video file resides on disk.
  • override : A boolean flag used to determine if we should skip Method #1 and go directly to the slower (but guaranteed accurate/error free) Method #2.

We make a call to cv2.VideoCapture  on Line 8 to obtain a pointer to the actual video file followed by initializing the total  number of frames in the video.

We then make a check on Line 13 to see if we should override . If so, we call count_frames_manual  (which we’ll define in the next section).

Otherwise, let’s see how Method #1 is actually implemented:

In order to determine the number of frames in a video file via the API by provided by OpenCV, we need to utilize what are called capture properties, or what OpenCV calls  CAP_PROP  — anytime you see a constant starting with CAP_PROP_* , you should know it’s related to video processing.

In OpenCV 3 the name of the frame count property is cv2.CAP_PROP_FRAME_COUNT  while in OpenCV 2.4 the property is named cv2.cv.CV_CAP_PROP_FRAME_COUNT .

Ideally, passing the respective property name into the .get  method of the video  pointer will allow us to obtain the total number of frames in the video (Lines 25-30).

However, there are cases where this method will fail based on your particular OpenCV install and video codecs.

If this is the case, we have wrapped our critical code section with a try/except  block. If an exception occurs we simply revert to counting the frames manually (Lines 33 and 34).

Finally, we release the video file pointer (Line 37) and return the total number of frames to the calling function (Line 40).

The slow way to count frames with OpenCV and Python

We’ve seen the fast, efficient method to counting frames in a video — let’s now move on to the slower method called count_frames_manual .

As we can see, count_frames_manual  requires only a single argument, video , which we assume to be a pointer instantiated by cv2.VideoCapture .

We then initialize the total number of frames read from the video  file, loop over the frames until we have reached the end of the video, and increment the total  counter along the way.

The total  is then returned to the calling function.

It’s worth mentioning that this method is totally accurate and error free. If you do get an error it’s almost certainly related to a problem with your video codecs or an invalid path to a video file.

There also might be times when using this function you get a total of zero frames returned. When this happens it’s 99% likely that:

  1. You supplied an invalid path to cv2.VideoCapture .
  2. You don’t have the proper video codecs installed and thus OpenCV cannot read the file. If this is the case you’ll need to install the proper video codecs, followed by re-compiling and re-installing OpenCV.

Counting frames in video files with OpenCV

Let’s go ahead and take our count_frames  method for a test drive.

To start, make sure you have installed the imutils library:

Otherwise, if you already have imutils  installed you should update to the latest version (> v0.3.9):

From there, let’s create our driver script named frame_counter.py :

We start by importing our required Python packages and parsing our command line arguments. We’ll require one switch followed by a second optional one:

  • --video : The path to our input video file.
  • --override : Whether or not to force a manual frame count. We’ll try to use the faster Method #1 by default.

We then make a call to count_frames  and display the result to our screen:

To test out this Python script, I’ve decided to use the trailer from my favorite movie, Jurassic Park:

How many frames do you think are in this video clip?

500?

5,000?

50,000?

Take your best guess and then let’s execute our Python script to find out.

Note: I used the website keepvid.com to download a .mp4 of the trailer. I do not own the copyrights to this movie or trailer. This script is only for demonstration and educational purposes. Please use responsibly.

To test out the fast method, execute the following command:

Figure 1: Determining the total number of frames in a video file using OpenCV properties.

Figure 1: Determining the total number of frames in a video file using OpenCV properties.

As my results demonstrate, it takes 0.803s to determine there are a total of 4,790 frames in the video file.

We can test out the slower method using this command:

Figure 2: Manually counting the total number of frames in a video file using OpenCV and Python.

Figure 2: Manually counting the total number of frames in a video file using OpenCV and Python.

Here we see that it takes 1m55s (an increase of approximately 14,221%) to return a frame count of 4,978 which differs Method #1 by 188 frames.

Why the discrepancy in frame counts?

It all comes down to fast and approximate versus slow but accurate.

Using OpenCV’s video capture properties we get a total frame count very fast, but it might not be 100% dead on. We also have the potential of this method failing entirely due to OpenCV/video codec versioning.

On the other hand, if we manually count the number of frames it will take us a long time, but the total number of returned frames will be exact.

In situations where you absolutely, positively, must have the exact count, go with Method #2.

If you need a rough approximation, go with Method #1 (unless it fails, then you’ll be reverting back to Method #2 anyway).

Summary

In this blog post I demonstrated two methods to count the number of frames in a video file using OpenCV and Python.

The first method is super quick, relying on OpenCV’s video property functionality, allowing us to (nearly) instantaneously determine the number of frames in a video file.

However, this method is quite buggy, is prone to failure (based on your OpenCV + video codec versions), and may even return nonsensical results.

In that case, we need to revert to our second method: manually counting the total number of frames in a video. While excruciatingly slow, this method has the advantage of being 100% accurate.

In order to balance speed versus potential failure I have created the count_frames  function and placed it inside the imutils library.

This function will attempt Method #1 first, and if it fails, automatically revert to Method #2.

In next week’s blog post we’ll be using this function to aid us in generating and visualizing video barcodes.

See you next week!

To be notified when the next blog posts goes live, be sure to enter your email address in the form below!

Downloads:

If you would like to download the code and images used in this post, please enter your email address in the form below. Not only will you get a .zip of the code, I’ll also send you a FREE 11-page Resource Guide on Computer Vision and Image Search Engines, including exclusive techniques that I don’t post on this blog! Sound good? If so, enter your email address and I’ll send you the code immediately!

, , , ,

7 Responses to Count the total number of frames in a video with OpenCV and Python

  1. Bharath January 9, 2017 at 12:51 pm #

    Hey! How are you doing.

    what do you think of chroma-keying. Do you have any posts on that.

    Thank you

    • Adrian Rosebrock January 10, 2017 at 1:09 pm #

      Chroma keying can be applied by using segmentation techniques. The best results come from using a background color that has significantly different color than your foreground allowing you to segment the foreground from the background and then apply the foreground to a new background. I cover the basics of color-based thresholding inside my book, Practical Python and OpenCV where you can learn more about this technique.

  2. tamim January 10, 2017 at 3:27 am #

    Great tutorials! Is it possible to make this program multi threaded using python Thread?

    • Adrian Rosebrock January 10, 2017 at 1:03 pm #

      Absolutely. I’ll be covering how to access video files via threads in a separate blog post. I have already covered threaded webcam streams in this post.

  3. Lior January 18, 2017 at 5:22 am #

    Thanks again for another great tutorial! In the manual part, isn’t using VideoCapture.Grab a better option? Just because it doesn’t read the entire frame and therefore MUCH faster.

    • Adrian Rosebrock January 18, 2017 at 7:05 am #

      Hey Lior — you are correct, using .grab in this context would be much faster. I’ll also be doing a blog post on threaded video stream access for further improvements in two weeks.

Trackbacks/Pingbacks

  1. Generating movie barcodes with OpenCV and Python - PyImageSearch - January 16, 2017

    […] In last week’s blog post I demonstrated how to count the number of frames in a video file. […]

Leave a Reply