Home > Net >  Create 7 hour video from 250.000 frames
Create 7 hour video from 250.000 frames

Time:10-01

I have 14 videos of 30 minutes (7 hours of videodata). I read in every video seperately, perform some morphological processing on each frame and then use cv2.imwrite() to save each processed frame. I'd like to make 1 big videofile of 7 hours of all processed frames. So far, I've been trying to use this code:

import numpy as np
import glob
 
img_array = []
for filename in glob.glob('C:/New folder/Images/*.jpg'):
    img = cv2.imread(filename)
    height, width, layers = img.shape
    size = (width,height)
    img_array.append(img)
 
 
out = cv2.VideoWriter('project.avi',cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
 
for i in range(len(img_array)):
    out.write(img_array[i])
out.release()

But an error is given when creating the img_array (memory overload). Is there any other way to make a 7 hour video from 250.000 frames?

Thank you.

CodePudding user response:

  • check that all pictures are of the same size
  • as stated by others, don't read all pictures at once. it's not necessary.

Usually I'd prefer to create the VideoWriter before the loop but you need the size for that, and you only know that after you've read the first image. That's why I initialize that variable to None and create the VideoWriter once I have the first image

Also: DIVX and .avi may work but that's not the best option. the built-in option is to use MJPG (with .avi), which is always available in OpenCV. I would however recommend .mkv and avc1 (H.264) for general video, or you could look for a lossless codec that stores data in RGB instead of YUV (which may distort color information from screenshots... and also drawn lines and other hard edges). You could try the rle (note the space) codec, which is a lossless codec based on run-length encoding.

import cv2 # `import cv2 as cv` is preferred these days
import numpy as np
import glob
 
out = None # VideoWriter initialized after reading the first image
outsize = None

for filename in glob.glob('C:/New folder/Images/*.jpg'):
    img = cv2.imread(filename)
    assert img is not None, filename # file could not be read

    (height, width, layers) = img.shape
    thissize = (width, height)

    if out is None: # this happens once at the beginning
        outsize = thissize
        out = cv2.VideoWriter('project.avi', cv2.VideoWriter_fourcc(*'DIVX'), 15, outsize)
        assert out.isOpened()
    else: # error checking for every following image
        assert thissize == outsize, (outsize, thissize, filename)

    out.write(img)

# finalize the video file (write headers/footers)
out.release()

You could also do this with an invocation of ffmpeg on the command line (or from your program):

How to create a video from images with FFmpeg?

CodePudding user response:

You don't need to store each frame inside an array. You can read the frame and write it to the video directly.

You can modify your code as:

import numpy as np
import glob
out = None
for filename in glob.glob('C:/New folder/Images/*.jpg'):
    img = cv2.imread(filename)
    if not out:
        height, width, layers = img.shape
        size = (width,height)
        out = cv2.VideoWriter('project.avi',cv2.VideoWriter_fourcc(*'DIVX'), 15, size)
    out.write(img)
out.release()
  • Related