Skip main navigation

Extracting video frames using OpenCV

How to extract individual frames from a video based on time position using OpenCV in Python

As we all know, video data contains a set of still images arranged in a sequence. This article shows you how to access frames at a specific time within a video file using OpenCV.

Opening a video with OpenCV

After first importing OpenCV as usual, all we need to open a video file is the name of a video file and the VideoCapture function:

import cv2
video = cv2.VideoCapture('sample.mp4')

Depending on what you put in the function brackets the VideoCapture function can take data from a range of different sources, for example a live feed from a camera or a stream from a remote device. For the purposes of this course though, all we need to know is that a string pointing to an existing video file will import that file for use in Python.

Metadata

Like image data, video data may contain all sorts of additional information or metadata other than the image frames themselves such as data created, and information about the capture device and other technical information. If we want a frame from a particular point of a video an important piece of information we can use is the numbers of frames per second, or fps. To get this information from a video in OpenCV we need to use the variable CAP_PROP_FPS and the function get as follows:

fps = video.get(cv2.CAP_PROP_FPS)
print('frames per second =',fps)

If you try this out with the attached sample video you should see the video is set to 25.0 fps.

Finding the frame at a particular time

As we know, video consists of a finite set of discrete image frames. These are ordered and can be found by the frame number. If we know the number of frames per second, and the time in the video we want to take a frame from, we can easily calculate the frame number we want:

minutes = 0
seconds = 28
frame_id = int(fps*(minutes*60 + seconds))
print('frame id =',frame_id)

This tells us that for 0 minutes 28 seconds into the video we need frame 700. The int() around the calculation makes sure the result we get is an integer value, since the that’s what we need to find a specific frame.

Extracting the frame from the video

Now we have a frame number of interest we need to set the video to the position we want using ‘set’ and extract the frame using ‘read’:

video.set(cv2.CAP_PROP_POS_FRAMES, frame_id)
ret, frame = video.read()

CAP_PROP_POS_FRAMES refers to the current frame position which we set to our variable frame_id. The read function returns the frame itself (that we name frame) and another value ‘ret’. If the frame is found this will be True otherwise it will be False.

Another way to extract the frame, without finding the frame number, is by using the time in milliseconds directly using CAP_PROP_POS_MSEC instead as follows:

t_msec = 1000*(minutes*60 + seconds)
video.set(cv2.CAP_PROP_POS_MSEC, t_msec)
ret, frame = video.read()

This should give exactly the same frame as before.

Displaying and saving the frame

Now we have our frame, we can display and/or save it as before in OpenCV:

cv2.imshow('frame', frame); cv2.waitKey(0)
cv2.imwrite('my_video_frame.png', frame)

Try this out for yourself using the sample video and code, which can be downloaded from https://github.com/nlmellor/PhenoDataCampp/tree/main/ImageAnalysis.

Can you use a loop to extract and display one frame for each minute of the video?

This article is from the free online

Introduction to Image Analysis for Plant Phenotyping

Created by
FutureLearn - Learning For Life

Reach your personal and professional goals

Unlock access to hundreds of expert online courses and degrees from top universities and educators to gain accredited qualifications and professional CV-building certificates.

Join over 18 million learners to launch, switch or build upon your career, all at your own pace, across a wide range of topic areas.

Start Learning now