Search code examples
pythonpython-3.xscikit-imageopencv

How do I extract the frames from a folder of mp4 videos and transfer them to another folder?


I have a folder full of mp4 clips (over 200). I want to take all those clips, extract their frames and send them to another folder to store all the frames in. This is what I have so far (part of the code) but it's only working when I have one mp4 file in the same folder:

import cv2     # for capturing videos
import math   # for mathematical operations
import matplotlib.pyplot as plt    # for plotting the images
import pandas as pd
from keras.preprocessing import image   # for preprocessing the images
import numpy as np    # for mathematical operations
from keras.utils import np_utils
from skimage.transform import resize   # for resizing images


count = 0
videoFile = "sample_vid.mp4"
cap = cv2.VideoCapture(videoFile)   # capturing the video from the given path
frameRate = cap.get(5) #frame rate
x=1
while(cap.isOpened()):
    frameId = cap.get(1) #current frame number
    ret, frame = cap.read()
    if (ret != True):
        break
    if (frameId % math.floor(frameRate) == 0):
        filename ="frame%d.jpg" % count;count+=1
        cv2.imwrite(filename, frame)
cap.release()
print ("Done!")

Again, i'm having some trouble dealing with the file directories in python and looping it so that it goes through all the files in another folder and send the frames extracted into another folder.


Solution

  • Use glob lib to find all mp4 files in your folder. Then run video2frames method against all videos.

    import cv2
    import math
    import glob
    
    def video2frames(video_file_path):
        count = 0
        cap = cv2.VideoCapture(video_file_path)
        frame_rate = cap.get(5)
        while cap.isOpened():
            frame_id = cap.get(1)
            ret, frame = cap.read()
            if not ret:
                break
            if frame_id % math.floor(frame_rate) == 0:
                filename = '{}_frame_{}.jpg'.format(video_file_path, count)
                count += 1
                cv2.imwrite(filename, frame)
        cap.release()
    
    videos = glob.glob('/home/adam/*.mp4')
    for i, video in enumerate(videos):
        print('{}/{} - {}'.format(i+1, len(videos), video))
        video2frames(video)
    

    Tested on two videos. Here is what I've got:

    enter image description here