captainsameer
captainsameer

Reputation: 55

Can't save a video in opencv

I am trying to save my video using opencv write method but the video is saved with 0 kb. what's wrong in my code.

import cv2

cap = cv2.VideoCapture("k1.mp4")
# assert cap.isOpened()
fgbg = cv2.bgsegm.createBackgroundSubtractorMOG()
fourcc = cv2.VideoWriter_fourcc(*'MP42')
out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (640,480))
# assert out.isOpened()

while cap.isOpened():
    ret, frame = cap.read()
    # if not ret: break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    fgmask = fgbg.apply(gray)
    thresh = 2
    maxValue = 255
    ret, th1 = cv2.threshold(fgmask, thresh, maxValue, cv2.THRESH_BINARY)

    color_space = cv2.applyColorMap(th1, cv2.COLORMAP_JET)
    result_vid = cv2.addWeighted(frame, 0.7, color_space, 0.7, 0)

    out.write(result_vid)

    cv2.imshow("vid", result_vid)
    if cv2.waitKey(20) == ord('q'):
        break

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

Upvotes: 3

Views: 6053

Answers (3)

Callum
Callum

Reputation: 115

Although your solution was to match the video codec and the video container format correctly, I wanted to add that another common reason the output file size is 0 kb when writing videos with OpenCV is a discrepancy between the captured video frame size and the output video frame size. This can be solved by replacing the hard coded output frame size with one calculated from the input video.

cap = cv2.VideoCapture('input.mp4')

w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
frameSize = (w, h)
fps = 20
fourCC = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourCC, fps, frameSize)

while True:
    ret, frame = cap.read()
    ...
    result_vid = ...
    ...
    out.write(result_vid)
    ...

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

Upvotes: 0

Sarthak Dandriyal
Sarthak Dandriyal

Reputation: 56

import cv2
cap = cv2.VideoCapture(0)
# assert cap.isOpened()

# Automatically grab width and height from video feed
# (returns float which we need to convert to integer for later on!)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# MACOS AND LINUX: *'XVID' (MacOS users may want to try VIDX as well just in case)
# WINDOWS *'VIDX'
writer = cv2.VideoWriter('local_capture.mp4', cv2.VideoWriter_fourcc(*'VIDX'),25, (width, height))
# assert writer.isOpened()

# This loop keeps recording until you hit Q or escape the window
# You may want to instead use some sort of timer, like from time import sleep and then just record for 5 seconds.
while True:
    # Capture frame-by-frame
    ret, frame = cap.read()
    # if not ret: break

    # Write the video
    writer.write(frame)

    # Display the resulting frame
    cv2.imshow('frame',frame)

    # This command let's us quit with the "q" button on a keyboard.
    # Simply pressing X on the window won't work!
    if cv2.waitKey(1) == ord('q'):
        break

cap.release()
writer.release()
cv2.destroyAllWindows()

Upvotes: 2

Rotem
Rotem

Reputation: 32084

The problem is that the video codec and the video container format do not match.

When executing your code, I am getting an error message (in the console windows):

OpenCV: FFMPEG: tag 0x3234504d/'MP42' is not supported with codec id 15 and format 'mp4 / MP4 (MPEG-4 Part 14)'
[mp4 @ 00000155e95dcec0] Could not find tag for codec msmpeg4v2 in stream #0, codec not currently supported in container

  • You are using fourcc = cv2.VideoWriter_fourcc(*'MP42'), and M420 applies video codec MPEG-4v2.
  • Video output file name is 'output.mp4'.
    The .mp4 extension applies MP4 container format.

Apparently .mp4 video file cannot contain video encoded with MPEG-4v2 codec.

You may either change codec, or change file format.

Example:

  • Changing output file name to 'output.avi' or 'output.wmv' works.
  • Changing the codec to MPEG-4: fourcc = cv2.VideoWriter_fourcc(*'mp4v') (and keeping file name 'output.mp4') also works.

One more issue:

Add the following code after ret, frame = cap.read():

if not ret:
    break;

Upvotes: 5

Related Questions