Resizing video using opencv and saving it

9.7k Views Asked by At

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()
1

There are 1 best solutions below

2
On BEST ANSWER

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)