stanley
stanley

Reputation: 1153

opencv - videowriter control bitrate

I have a working python script that uses the video writer from opencv.

source https://gist.github.com/stanchiang/b4e4890160a054a9c1d65f9152172600


If i take in a file, and regardless of whether I simply pass the video frame through to the writer (effectively duplicating the file) or if i try to edit the frame, the file is always larger. I would like for it to be no larger than the original (since if you read my script i'm blurring a lot of stuff).

After checking their metadata, with ffprobe -v quiet -print_format json -show_format -show_streams inputFile.mp4 I notice that the bitrate of the new file is over 5.5x higher than before.

source https://www.diffchecker.com/8r2syeln


since bitrate is a big determinant of file size, I'm wondering if

  1. i can hardcode the desired bitrate of the new file through the video writer
  2. whether for some reason the heavily increased bit rate is needed

Upvotes: 9

Views: 15307

Answers (2)

abhiTronix
abhiTronix

Reputation: 1402

My VidGear Python Library's WriteGear API automates the process of pipelining OpenCV frames into FFmpeg on any platform and at the same time provides same opencv-python syntax. Here's a basic python example:

# import libraries
from vidgear.gears import WriteGear
import cv2

output_params = {"-vcodec":"libx264", "-crf": 0, "-preset": "fast"} #define (Codec,CRF,preset) FFmpeg tweak parameters for writer

stream = cv2.VideoCapture(0) #Open live webcam video stream on first index(i.e. 0) device

writer = WriteGear(output_filename = 'Output.mp4', compression_mode = True, logging = True, **output_params) #Define writer with output filename 'Output.mp4' 

# infinite loop
while True:
    
    (grabbed, frame) = stream.read()
    # read frames

    # check if frame empty
    if not is grabbed:
        #if True break the infinite loop
        break
    

    # {do something with frame here}
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)


    # write a modified frame to writer
    writer.write(gray) 
       
        # Show output window
    cv2.imshow("Output Frame", frame)

    key = cv2.waitKey(1) & 0xFF
    # check for 'q' key-press
    if key == ord("q"):
        #if 'q' key-pressed break out
        break

cv2.destroyAllWindows()
# close output window

stream.release()
# safely close video stream
writer.close()
# safely close writer

Source:https://abhitronix.github.io/vidgear/latest/gears/writegear/compression/usage/#using-compression-mode-with-opencv

You can check out VidGear Docs for more advanced applications and features.

Upvotes: 1

stanley
stanley

Reputation: 1153

basically this answer https://stackoverflow.com/a/13298538/1079379

# import packages
from PIL import Image
from subprocess import Popen, PIPE
from imutils.video import VideoStream
from imutils.object_detection import non_max_suppression
from imutils import paths
import cv2
import numpy as np
import imutils

# ffmpeg setup
p = Popen(['ffmpeg', '-y', '-f', 'image2pipe', '-vcodec', 'mjpeg', '-r', '24', '-i', '-', '-vcodec', 'h264', '-qscale', '5', '-r', '24', 'video.mp4'], stdin=PIPE)

video = cv2.VideoCapture('videos.mp4')

while True:
    ret, frame = video.read()
    if ret:
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        im = Image.fromarray(frame)
        im.save(p.stdin, 'JPEG')
    else:
        break

p.stdin.close()
p.wait()
video.release()
cv2.destroyAllWindows()

Upvotes: 5

Related Questions