mchd
mchd

Reputation: 3163

How to add a delay when saving video frames as images

I have a series of videos and I want to save frames from them as images. This is my code:

import os, cv2

current_dir = os.getcwd()
training_videos = '../../Videos/training_videos/'

if not os.path.exists(current_dir + '/training_images/'):
    os.mkdir(current_dir + '/training_images/')

for i in os.listdir(training_videos):

    video = cv2.VideoCapture('../../Videos/training_videos/' + i)

    currentFrame = 0

    while (True):
        # Capture frame-by-frame
        ret, frame = video.read()

        # Saves image of the current frame in jpg file
        name = current_dir + '/training_images/frame' + str(currentFrame) + '.png'
        print('Creating...' + name)
        cv2.imwrite(name, frame)

        # To stop duplicate images
        currentFrame += 1

This code works but unfortunately, it takes a frame at every millisecond. This is not something I want. Instead, I want to save a frame at every 5 or 10 seconds. I thought about adding a time delay but that wouldn't really work because the videos are not live streams so after 5 seconds, it'll just take the screenshot right after the previous millisecond.

Upvotes: 0

Views: 1235

Answers (2)

Axiumin_
Axiumin_

Reputation: 2145

There's likely an more efficient way, but you can do this by using the frame rate of the video and then processing the image every FRAME_RATE * 5 frames.

Your code would look something like this (let me know if this doesn't work as I haven't ran this on my PC):

import os, cv2

current_dir = os.getcwd()
training_videos = '../../Videos/training_videos/'

if not os.path.exists(current_dir + '/training_images/'):
    os.mkdir(current_dir + '/training_images/')

for i in os.listdir(training_videos):

    video = cv2.VideoCapture('../../Videos/training_videos/' + i)
    fps = video.get(cv2.CAP_PROP_FPS)

    currentFrame = 0

    while video.isOpened():
        # Capture frame-by-frame
        ret, frame = video.read()

        if (video):
            # Write current frame
            name = current_dir + '/training_images/frame' + str(currentFrame) + '.png'
            print('Creating...' + name)
            cv2.imwrite(name, frame)

            currentFrame += fps * 5
            # Skip to next 5 seconds
            video.set(cv2.CAP_PROP_POS_FRAMES, currentFrame)

Upvotes: 1

Jasar Orion
Jasar Orion

Reputation: 332

you can use time.sleep(5) try it:

import os, cv2
import time
framesToSkip = 120

current_dir = os.getcwd()
training_videos = '../../Videos/training_videos/'

if not os.path.exists(current_dir + '/training_images/'):
    os.mkdir(current_dir + '/training_images/')

for i in os.listdir(training_videos):

    video = cv2.VideoCapture('../../Videos/training_videos/' + i)

    currentFrame = 0

    while (True):
        # To stop duplicate images
        currentFrame += 1
        if currentFrame % framesToSkip != 0:
            continue
        # Capture frame-by-frame
        ret, frame = video.read()

        # Saves image of the current frame in jpg file
        name = current_dir + '/training_images/frame' + str(currentFrame) + '.png'
        print('Creating...' + name)
        cv2.imwrite(name, frame)
        time.sleep(5)

        

it will pause for 5 seconds and take save the next frame.

Upvotes: 0

Related Questions