-1

I have this python code that should make a video:

import cv2
import numpy as np

out = cv2.VideoWriter("/tmp/test.mp4",
                      cv2.VideoWriter_fourcc(*'MP4V'),
                      25,
                      (500, 500),
                      True)
data = np.zeros((500,500,3))
for i in xrange(500):
    out.write(data)

out.release()

I expect a black video but the code throws an assertion error:

$ python test.py
OpenCV(3.4.1) Error: Assertion failed (image->depth == 8) in writeFrame, file /io/opencv/modules/videoio/src/cap_ffmpeg.cpp, line 274
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    out.write(data)
cv2.error: OpenCV(3.4.1) /io/opencv/modules/videoio/src/cap_ffmpeg.cpp:274: error: (-215) image->depth == 8 in function writeFrame

I tried various fourcc values but none seem to work.

fakedrake
  • 6,528
  • 8
  • 41
  • 64
  • 1
    You didn't specify data type in `np.zeros` -- by default it's a 64bit float, but the VideoWriter only supports 8bit channel depth. – Dan Mašek Aug 24 '18 at 16:19
  • 1
    Exactly! Just use the line `data = np.zeros((500,500,3), dtype = np.uint8)` instead. – Jeru Luke Aug 24 '18 at 16:23

2 Answers2

2

According to @jeru-luke and @dan-masek's comments:

import cv2
import numpy as np

out = cv2.VideoWriter("/tmp/test.mp4",
                      cv2.VideoWriter_fourcc(*'mp4v'),
                      25,
                      (1000, 500),
                      True)

data = np.transpose(np.zeros((1000, 500,3), np.uint8), (1,0,2))
for i in xrange(500):
    out.write(data)

out.release()
fakedrake
  • 6,528
  • 8
  • 41
  • 64
  • 1
    Also have a look at [this answer](https://stackoverflow.com/questions/51914683/how-to-make-video-from-an-updating-numpy-array-in-python/51915019#51915019) where the data is normalized before writing it to video. – Jeru Luke Aug 24 '18 at 16:26
2

The problem is that you did not specify the data type of elements when calling np.zeros. As the documentation states, by default numpy will use float64.

>>> import numpy as np
>>> np.zeros((500,500,3)).dtype
dtype('float64')

However, the VideoWriter implementation only supports 8 bit image depth (as the "(image->depth == 8)" part of the error message suggests).

The solution is simple -- specify the appropriate data type, in this case uint8.

data = np.zeros((500,500,3), dtype=np.uint8)
Dan Mašek
  • 17,852
  • 6
  • 57
  • 85