How to Fix Images Being Written to Video in Random Order

Question:

I am attempting to write 271 images of a simulation that are already in numerical order (‘0.jpg’,’1.jpg’, …, ‘271.jpg’) into a video. cv2.videoWriter appears to be writing all of these images in random order, producing a video that doesn’t align with what is supposed to happen in the simulation.

I have already tried using glob, which produces the same result as using os.path

import numpy as np
import os
from os.path import isfile, join

pathIn= 'path/simulation/'
pathOut = 'video.avi'

fps = 10 

frame_array = []

files = [f for f in os.listdir(pathIn) if isfile(join(pathIn, f))]

# for sorting the file names properly
files.sort(key = lambda x: x[5:-4])
files.sort()
frame_array = []
files = [f for f in os.listdir(pathIn) if isfile(join(pathIn, f))]

for i in range(len(files)):
    filename=pathIn + files[i]
    # reading each file
    img = cv2.imread(filename)
    height, width, layers = img.shape
    size = (width,height)

    # inserting the frames into an image array
    frame_array.append(img)

out = cv2.VideoWriter(pathOut,cv2.VideoWriter_fourcc(*'DIVX'), fps, size)

for i in range(len(frame_array)):
    # writing to a image array
    out.write(frame_array[i])
out.release()

Expected order of images converted to video:

‘0.jpg’, ‘1.jpg’, … ‘271.jpg’

Actual result:

’31.jpg’, ‘230.jpg’, ’12.jpg’, …

Asked By: CZP3

||

Answers:

There are two problems with

files.sort(key = lambda x: x[5:-4])
files.sort()

First, '0.jpg'[5:-4] produces an empty string. I think you want something like

file.sort(key = lambda x: int(x[:-4]))

Second, you’re throwing away the result by sorting again. Drop the second sort.

Answered By: Dave W. Smith

I was facing the same problem with fourcc = "mp4v" and ".mp4" extension.

I changed to fourcc = "DIVX" and ".avi" extension, and the order of the written frames was kept as I sorted the filenames.

Since your case is DIVX-avi, it may be worth a shot to try another pair fourcc-extension

Answered By: solisoares

In my case I fixed that changing the coded.

Code with issues (order of frames was wrong – as if the video was playing forward and back in an infinite loop):

video_writer = cv2.VideoWriter(
    'video.avi',
    cv2.VideoWriter_fourcc(*"MPEG"),
    fps,
    (width, height)
)

Working code:

video_writer = cv2.VideoWriter(
    'video.avi',
    cv2.VideoWriter_fourcc(*"XVID"),
    fps,
    (width, height)
)
Answered By: user1315621
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.