15

I am trying to use the openCV VideoWriter class to generate a video from numpy arrays. I am using the following code:

import numpy as np
import cv2
size = 720*16//9, 720
duration = 2
fps = 25
out = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'X264'), fps, size)
for _ in range(fps * duration):
    data = np.random.randint(0, 256, size, dtype='uint8')
    out.write(data)
out.release()

The codec seems to be installed as ffmpeg can do conversions to the x264 codec and libx264 is installed. The code runs without warnings, however the videos generated seem to contain no data since I always get the following message when trying to read them with mpv:

[ffmpeg/demuxer] avi: Could not find codec parameters for stream 0 (Video: h264 (X264 / 0x34363258), none, 1280x720): unspecified pixel format

What could be the cause of this issue?

1 Answer 1

21

The first issue is that you are trying to create a video using black and white frames while VideoWriter assumes color by default. VideoWriter has a 5th boolean parameter where you can pass False to specify that the video is to be black and white.

The second issue is that the dimensions that cv2 expects are the opposite of numpy. Thus, size should be (size[1], size[0]).

A possible further problem is the codec being used. I have never been able to get "X264" to work on my machine and instead have been using "mp4v" as the codec and ".mp4" for the container type in order to get an H.264 encoded output.

After all of these issues are fixed, this is the result. Please try this and see if it works for you:

import numpy as np
import cv2
size = 720*16//9, 720
duration = 2
fps = 25
out = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (size[1], size[0]), False)
for _ in range(fps * duration):
    data = np.random.randint(0, 256, size, dtype='uint8')
    out.write(data)
out.release()
Sign up to request clarification or add additional context in comments.

6 Comments

This works, I just wanted to add that the X264 codec does also work, but generates a much lower quality video than mp4v
Great! Maybe X264 doesn't work for me because I don't have libx264 installed? Anyway, I'm glad to hear that it worked for you :)
Update: I have since found that the video is not being H264 encoded with the method in the above code. I found a solution using one of Cisco's OpenH264 binaries. It must be downloaded and placed in the same working directory. OpenCV seems to find it automatically as long as the binary version is 1.8 and the name is unchanged (newer versions don't work as of the date of this comment). github.com/cisco/openh264/releases
Forgot to mention, when using Cisco's OpenH264 binary, change the fourcc code to "avc1".
Thank you man. I was really looking for this. Maybe you should put this answer on any other possible question relating to this problem (such as making a video with stack of images in python). I searched hard to finally this page came up.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.