Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

openCV video saving in python

Tags:

python

opencv

People also ask

How do I save an OpenCV video in Python?

With the cv2. VideoWriter() function, with the first parameter, we choose where the file will be saved and what its name will be, along with the type of file it will be. In this case, it will be an mp4 video file. If saving in the current working directory, you will simply specify the name and type of video file.

How do I save a video from OpenCV?

OpenCV also allows us to save that operated video for further usage. For saving images, we use cv2. imwrite() which saves the image to a specified file location. But, for saving a recorded video, we create a Video Writer object.


Try this. It's working for me (Windows 10).

import numpy as np
import cv2

cap = cv2.VideoCapture(0)

# Define the codec and create VideoWriter object
#fourcc = cv2.cv.CV_FOURCC(*'DIVX')
#out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
out = cv2.VideoWriter('output.avi', -1, 20.0, (640,480))

while(cap.isOpened()):
    ret, frame = cap.read()
    if ret==True:
        frame = cv2.flip(frame,0)

        # write the flipped frame
        out.write(frame)

        cv2.imshow('frame',frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()

In my case, I found that size of Writer have to matched with the frame size both from camera or files. So that I read the frame size first and apply to writer setting as below.

(grabbed, frame) = camera.read()
fshape = frame.shape
fheight = fshape[0]
fwidth = fshape[1]
print fwidth , fheight
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (fwidth,fheight))

jveitchmichaelis at https://github.com/ContinuumIO/anaconda-issues/issues/223 provided a thorough answer. Here I copied his answer:

The documentation in OpenCV says (hidden away) that you can only write to avi using OpenCV3. Whether that's true or not I've not been able to determine, but I've been unable to write to anything else.

However, OpenCV is mainly a computer vision library, not a video stream, codec and write one. Therefore, the developers tried to keep this part as simple as possible. Due to this OpenCV for video containers supports only the avi extension, its first version.

From: http://docs.opencv.org/3.1.0/d7/d9e/tutorial_video_write.html

My setup: I built OpenCV 3 from source using MSVC 2015, including ffmpeg. I've also downloaded and installed XVID and openh264 from Cisco, which I added to my PATH. I'm running Anaconda Python 3. I also downloaded a recent build of ffmpeg and added the bin folder to my path, though that shouldn't make a difference as its baked into OpenCV.

I'm running in Win 10 64-bit.

This code seems to work fine on my computer. It will generate a video containing random static:

writer = cv2.VideoWriter("output.avi",
cv2.VideoWriter_fourcc(*"MJPG"), 30,(640,480))

for frame in range(1000):
    writer.write(np.random.randint(0, 255, (480,640,3)).astype('uint8'))

writer.release()

Some things I've learned through trial and error:

  • Only use '.avi', it's just a container, the codec is the important thing.
  • Be careful with specifying frame sizes. In the constructor you need to pass the frame size as (column, row) e.g. 640x480. However the array you pass in, is indexed as (row, column). See in the above example how it's switched?

  • If your input image has a different size to the VideoWriter, it will fail (often silently)

  • Only pass in 8 bit images, manually cast your arrays if you have to (.astype('uint8'))
  • In fact, never mind, just always cast. Even if you load in images using cv2.imread, you need to cast to uint8...
  • MJPG will fail if you don't pass in a 3 channel, 8-bit image. I get an assertion failure for this at least.
  • XVID also requires a 3 channel image but fails silently if you don't do this.
  • H264 seems to be fine with a single channel image
  • If you need raw output, say from a machine vision camera, you can use 'DIB '. 'RAW ' or an empty codec sometimes works. Oddly if I use DIB, I get an ffmpeg error, but the video is saved fine. If I use RAW, there isn't an error, but Windows Video player won't open it. All are fine in VLC.

In the end I think the key point is that OpenCV is not designed to be a video capture library - it doesn't even support sound. VideoWriter is useful, but 99% of the time you're better off saving all your images into a folder and using ffmpeg to turn them into a useful video.


You need to get the exact size of the capture like this:

import cv2

cap = cv2.VideoCapture(0)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) + 0.5)
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) + 0.5)
size = (width, height)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('your_video.avi', fourcc, 20.0, size)

while(True):
    _, frame = cap.read()
    cv2.imshow('Recording...', frame)
    out.write(frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
out.release()
cv2.destroyAllWindows()

Please make sure to set correct width and height. You can set it like bellow

cv2.VideoWriter('output.avi', fourcc, 20.0, (int(cap.get(3)), int(cap.get(4))))

I also faced same problem but it worked when I used 'MJPG' instead of 'XVID'

I used

fourcc = cv2.VideoWriter_fourcc(*'MJPG')

instead of

fourcc = cv2.VideoWriter_fourcc(*'XVID')