12

I have a problem with writing a toy example video using opencv2.3.1 VideoWriter, here is how I do it:

writer = cv2.VideoWriter('test1.avi',cv.CV_FOURCC('P','I','M','1'),25,(640,480))
for i in range(1000):
    x = np.random.randint(10,size=(480,640)).astype('uint8')
    writer.write(x)
#del writer (with or without tested)

I tried every possible combination resulting with a 0 bytes file if the extension was mpg, and 5.5kb if it was avi. I should say that some pointed out that I should build the ffmpeg library from source and not apt-get it. Well I did that on a fresh machine based on the help of this site http://vinayhacks.blogspot.com/2011/11/installing-opencv-231-with-ffmpeg-on-64.html. which also presented an error while compiling opencv(the error was related to ffmpeg). Now I am really out of ideas, How to generate a video using OPENCV?

Thanks in advance

JustInTime
  • 2,716
  • 5
  • 22
  • 25
  • If, for some reason, `cv2.VideoWriter()'` failed .... `writer` would be nil. How about testing that before executing the loop? – karlphillip Feb 14 '12 at 16:48
  • when I write writer.isOpened it returns for me True, therefore i dont think it is None – JustInTime Feb 14 '12 at 21:18
  • I'm not saying it's the case, I'm saying that is good practice to do it and it will protect you from a lot of headaches in the future. – karlphillip Feb 15 '12 at 00:05

3 Answers3

11

VideoWriter has last argument isColor with default value True. So if you change it to False then you can write your 2D arrays.

import cv2
import numpy as np

writer = cv2.VideoWriter('test1.avi', cv2.VideoWriter_fourcc(*'PIM1'), 25, (640, 480), False)
for i in range(100):
    x = np.random.randint(255, size=(480, 640)).astype('uint8')
    writer.write(x)
4

Hello I am new to opencv and I had this same problem. It appears that the writer.write(x) Needs x to be an array whit RGB values and not scalars. I solved the issue by doing this:

import cv2
import cv2.cv as cv
import numpy as np

writer = cv2.VideoWriter('test1.avi',cv.CV_FOURCC('P','I','M','1'),25,(640,480))
for i in range(1000):
    x = np.random.randint(255,size=(480,640)).astype('uint8')
    x = np.repeat(x,3,axis=1)
    x = x.reshape(480, 640, 3)
    writer.write(x)

I assume there are cleaner ways to do it but I haven't found any.

creyesk
  • 343
  • 3
  • 9
  • 10
    just a side note (so that future me will not waste time again) that opencv expects (width, height) but numpy array needs to be (height, width). that's why 640,480 for videowriter but 480,640 for np. videowriter will silently fails if dimensions not matched. – otterb Oct 02 '15 at 08:50
1

Which OS are you using? Are you sure your system have PIM1 codec installed?

I use windows, and I can use cv.FOURCC(*"DIB ") for uncompressed video, or use -1 to show a codec dialog.

After install ffdshow, I can use cv.FOURCC(*"ffds") to encode the video by MPEG-4.

HYRY
  • 94,853
  • 25
  • 187
  • 187
  • I am running Ubuntu 10.04, already tried it with -1, but it present for me this error message error: (-210) Gstreamer Opencv backend doesn't support this codec acutally. in function CvVideoWriter_GStreamer::open – JustInTime Feb 15 '12 at 08:47