I’ve worked with videos a lot over the years and one thing that I often need to do is to extract the frames from a video and save them as individual images. Over time I have had to work with bigger and more error-prone video files and have recently settled on a nice script that I thought I would share.
Let’s start with the basic function which can extract frames from a single video without too much effort. This function called
extract_frames() takes a video path, a path to a frames directory, and a few extras like whether we want to overwrite frames if they already exist, or only do every x many frames.
You might notice that we are using a while loop with a kinda odd looking
while_safety counter. This is there because sometimes OpenCV will return empty frames, in which case we want to just keep reading without incrementing the
frame counter. This increases any potential that already existed for an endless loop, which is why the
while_safety counter is used and incremented every time the
frame counter isn’t.
Although the above code is simple, it is actually pretty slow, it turns out extracting and saving frames takes a while. Luckily these days computers tend to have multiple CPU cores that can do things in parallel. So let’s extend upon the above code to add parallel processing over all CPU cores.
To do this we write a wrapping function
video_to_frames() that firstly breaks a video into chunks of length
chunk_size, and then calls the
extract_frames() function seen above on each chunk.