5

I'm trying to re-size the video using opencv and then save it back to my system.The code works and does not give any error but output video file is corrupted. The fourcc I am using is mp4v works well with .mp4 but still the output video is corrupted. Need Help.

import numpy as np
    import cv2
    import sys
    import re
    vid=""
    
    if len(sys.argv)==3:
        vid=sys.argv[1]
        compress=int(sys.argv[2])
    else:
        print("File not mentioned or compression not given")
        exit()
    
    if re.search('.mp4',vid):
        print("Loading")
    else:
        exit()
    
    cap = cv2.VideoCapture(0)
    ret, frame = cap.read()
    
    def rescale_frame(frame, percent=75):
        width = int(frame.shape[1] * percent/ 100)
        height = int(frame.shape[0] * percent/ 100)
        dim = (width, height)
        return cv2.resize(frame, dim, interpolation =cv2.INTER_AREA)
    
    FPS= 15.0
    FrameSize=(frame.shape[1], frame.shape[0])
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    
    out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)
    
    while(cap.isOpened()):
        ret, frame = cap.read()
    
        # check for successfulness of cap.read()
        if not ret: break
        
        rescaled_frame=rescale_frame(frame,percent=compress)
        # Save the video
        out.write(rescaled_frame)
    
        cv2.imshow('frame',rescaled_frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
             break
    
    cap.release()
    out.release()
    cv2.destroyAllWindows()
Mitul Tandon
  • 53
  • 1
  • 5
  • Refer [this](https://stackoverflow.com/questions/57216693/how-to-save-a-video-in-python-opencv) for any issues related to saving video –  Sep 05 '20 at 18:37
  • out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize) ...removing 0 surprisingly solved this issue. However I'm unware of the logic behind it. – Mitul Tandon Sep 05 '20 at 19:15

1 Answers1

8

The problem is the VideoWriter initialization.

You initialized:

out = cv2.VideoWriter('Video_output.mp4', fourcc, FPS, FrameSize, 0)

The last parameter 0 means, isColor = False. You are telling, you are going to convert frames to the grayscale and then saves. But there is no conversion in your code.

Also, you are resizing each frame in your code based on compress parameter.

If I use the default compress parameter:

cap = cv2.VideoCapture(0)

if cap.isOpened():
    ret, frame = cap.read()
    rescaled_frame = rescale_frame(frame)
    (h, w) = rescaled_frame.shape[:2]
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    writer = cv2.VideoWriter('Video_output.mp4',
                             fourcc, 15.0,
                             (w, h), True)
else:
    print("Camera is not opened")

Now we have initialized the VideoWriter with the desired dimension.


Full Code:

import time
import cv2


def rescale_frame(frame_input, percent=75):
    width = int(frame_input.shape[1] * percent / 100)
    height = int(frame_input.shape[0] * percent / 100)
    dim = (width, height)
    return cv2.resize(frame_input, dim, interpolation=cv2.INTER_AREA)


cap = cv2.VideoCapture(0)

if cap.isOpened():
    ret, frame = cap.read()
    rescaled_frame = rescale_frame(frame)
    (h, w) = rescaled_frame.shape[:2]
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    writer = cv2.VideoWriter('Video_output.mp4',
                             fourcc, 15.0,
                             (w, h), True)
else:
    print("Camera is not opened")

while cap.isOpened():
    ret, frame = cap.read()

    rescaled_frame = rescale_frame(frame)

    # write the output frame to file
    writer.write(rescaled_frame)

    cv2.imshow("Output", rescaled_frame)
    key = cv2.waitKey(1) & 0xFF
    if key == ord("q"):
        break


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

Possible Question: I don't want to change my VideoWriter parameters, what should I do?

Answer: Then you need to change your frames, to the gray image:

while cap.isOpened():
    # grab the frame from the video stream and resize it to have a
    # maximum width of 300 pixels
    ret, frame = cap.read()

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
Hammad
  • 529
  • 7
  • 17
Ahmet
  • 7,527
  • 3
  • 23
  • 47
  • Thank for such a detailed explanation. I initialized the VideoWriter with the size of the frames to which I'm going to compress it. But now i understand why i was getting a corrupt file thanks to your answer. – Mitul Tandon Sep 06 '20 at 19:07
  • Glad, if I could help :) – Ahmet Sep 06 '20 at 19:08