11
votes

I must create low resolution AVI videos using a large number of jpeg images contained in individual directories. I have nearly one hundred directories, and each directory may contain many thousands of images.

In order to automate this process, I have written a python script using OpenCV to create a video object, load each image from a given directory, and write each image to a specific video file for that directory. All this works great. My problem is how to control the compression quality for the video object.

The VideoWriter module accepts 5 parameters. The second parameter, 'fourcc', sets the compression code.

cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor])

We can specify a compression code within cv2.VideoWriter using a "four character code" (i.e. fourcc).

fourcc = cv2.cv.CV_FOURCC('M','S','V','C') #Microspoft Video 1

This approach works except the compression quality of the video object is always set at it's maximum.

If we let fourcc = -1, a Windows Video Compression dialog box opens which allows the user to select a video compression AND set Compression Quality (or Temporal Quality Ratio) between 0 and 100.

screenshot of this Windows Video Compression dialog box

Each video must be an AVI and must meet certain file size requirements. The video file is too big if the maximum compression quality is used. However, requiring the user to select the video compression and compression quality for each video defeats the script's automation.

So, how does one specify a the compression quality for the video object without using the Windows Video Compression dialog box?

The entirety of my code is posted below

import cv2, os

Workspace = "J:\jpg to AVI test"
year = "2014"
file_extension = "avi"
Image_file_dir = Workspace + "\\12 - ECD-BONNETT CREEK Y INT (" + year + ")"
print Image_file_dir
Image_file_list = os.listdir(Image_file_dir)
print "Image_file_list: " + str(Image_file_list)

img_cnt = 0

for Image_file in Image_file_list:

    if Image_file.split(".")[-1] == "jpg":

        Image_file_path = Image_file_dir + "\\" + Image_file
        print Image_file_path

        img1 = cv2.imread(Image_file_path)

        height , width , layers =  img1.shape

        break

fourcc = cv2.cv.CV_FOURCC('M','S','V','C') #Microspoft Video 1
##fourcc = -1
video_object = Workspace + "\\12 - ECD-BONNETT CREEK Y INT (" + year + ")." + file_extension
video = cv2.VideoWriter(video_object,\
                        fourcc,\
                        9,\
                        (width,height))

for Image_file in Image_file_list:

    if Image_file.split(".")[-1] == "jpg":

        img_cnt += 1
        Image_file_path = Image_file_dir + "\\" + Image_file
        print str(img_cnt) + ") " + Image_file_path

        img1 = cv2.imread(Image_file_path)

        video.write(img1)

cv2.destroyAllWindows() 
video.release()
1

1 Answers

13
votes

Sorry! OpenCV has no interface to let you configure the compression rate.

I recently needed to do a similar thing. My course of action was to invoke ffmpeg programatically and use it to convert the AVI created by OpenCV into a MP4 file.

This turned a 100MB file into less than 900KB.