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