user13074756
user13074756

Reputation: 413

Convert Video to Frames in Python - 1 FPS

I have a video that is 30 fps. I need to extract frames from the video at 1 FPS. How is this possible in Python?

I have the below code I got from online but I am not sure if its extracting frames in 1 FPS. Please help!

# Importing all necessary libraries 
import cv2 
import os 
  
# Read the video from specified path 
cam = cv2.VideoCapture("C:\\Users\\Admin\\PycharmProjects\\project_1\\openCV.mp4") 
  
try: 
      
    # creating a folder named data 
    if not os.path.exists('data'): 
        os.makedirs('data') 
  
# if not created then raise error 
except OSError: 
    print ('Error: Creating directory of data') 
  
# frame 
currentframe = 0
  
while(True): 
      
    # reading from frame 
    ret,frame = cam.read() 
  
    if ret: 
        # if video is still left continue creating images 
        name = './data/frame' + str(currentframe) + '.jpg'
        print ('Creating...' + name) 
  
        # writing the extracted images 
        cv2.imwrite(name, frame) 
  
        # increasing counter so that it will 
        # show how many frames are created 
        currentframe += 1
    else: 
        break
  
# Release all space and windows once done 
cam.release() 
cv2.destroyAllWindows()

Upvotes: 1

Views: 10598

Answers (3)

ego-lay atman-bay
ego-lay atman-bay

Reputation: 109

Here's the code that I found works best.

import os
import cv2
import moviepy.editor

def getFrames(vid, output, rate=0.5, frameName='frame'):
    vidcap = cv2.VideoCapture(vid)
    clip = moviepy.editor.VideoFileClip(vid)

    seconds = clip.duration
    print('duration: ' + str(seconds))
    
    count = 0
    frame = 0
    
    if not os.path.isdir(output):
        os.mkdir(output)
    
    success = True
    while success:
        vidcap.set(cv2.CAP_PROP_POS_MSEC,frame*1000)      
        success,image = vidcap.read()

        ## Stop when last frame is identified
        print(frame)
        if frame > seconds or not success:
            break

        print('extracting frame ' + frameName + '-%d.png' % count)
        name = output + '/' + frameName + '-%d.png' % count # save frame as PNG file
        cv2.imwrite(name, image)
        frame += rate
        count += 1

The value for the rate argument is 1/fps

Upvotes: 1

user13074756
user13074756

Reputation: 413

KPS = 1# Target Keyframes Per Second
VIDEO_PATH = "video1.avi"#"path/to/video/folder" # Change this
IMAGE_PATH = "images/"#"path/to/image/folder" # ...and this 
EXTENSION = ".png"
cap = cv2.VideoCapture(VIDEO_PATH)
fps = round(cap.get(cv2.CAP_PROP_FPS))
print(fps)
# exit()
hop = round(fps / KPS)
curr_frame = 0
while(True):
    ret, frame = cap.read()
ifnot ret: break
if curr_frame % hop == 0:
        name = IMAGE_PATH + "_" + str(curr_frame) + EXTENSION
        cv2.imwrite(name, frame)
    curr_frame += 1
cap.release()

Upvotes: 2

sudohumberto
sudohumberto

Reputation: 120

This is the code I use when I need to extract frames from videos:


# pip install opencv-python

import cv2
import numpy as np

# video.mp4 is a video of 9 seconds
filename = "video.mp4"

cap = cv2.VideoCapture(filename)
cap.set(cv2.CAP_PROP_POS_AVI_RATIO,0)
frameCount = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
frameWidth = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frameHeight = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
videoFPS = int(cap.get(cv2.CAP_PROP_FPS))

print (f"frameCount: {frameCount}")
print (f"frameWidth: {frameWidth}")
print (f"frameHeight: {frameHeight}")
print (f"videoFPS: {videoFPS}")

buf = np.empty((
    frameCount,
    frameHeight,
    frameWidth,
    3), np.dtype('uint8'))

fc = 0
ret = True

while (fc < frameCount):
    ret, buf[fc] = cap.read()
    fc += 1

cap.release()
videoArray = buf

print (f"DURATION: {frameCount/videoFPS}")

You can see how to extract features of the video like frameCount, frameWidth, frameHeight, videoFPS

At the end, the duration should be the number of frames divided by the videoFPS variable.

All the frames are stored inside buf, so if you want to extract only 1 Frame iterate over buf and extract only 9 frames (increasing your video FPS each iteration).

Upvotes: 1

Related Questions