0

This is my first attempt at making a video file and I seem to be very clumsy. Inspired by these instructions to put several images in a single video, I modified the code by creating a function that can loop through the folder with the images. But it is taking too long. I thought it was because there are many images, but even if I only use two images to do it, it still runs forever.

I get no error message, the script just never stops.

Could anybody please explain what is wrong with my code? There must be something silly which I didn't spot and is making it an infinite loop or something...

import cv2
import os

forexample = "C:/Users/me/Pictures/eg/"

eg = cv2.imread(forexample+'figure.jpg')
height , width , layers =  eg.shape

print "ok, got that"

def makeVideo(imgPath, videodir, videoname, width,height):
    for img in os.listdir(imgPath):
        video = cv2.VideoWriter(videodir+videoname,-1,1,(width,height))
        shot = cv2.imread(img)    
        video.write(shot)
    print "one video done"


myexample = makeVideo(forexample,forexample, "example.avi", width, height)

cv2.destroyAllWindows()
myexample.release()

Running on a windows machine, Python 2.7.12, cv2 3.3.0

UPDATE Eventually created the video using FFmpeg.

durbachit
  • 4,626
  • 10
  • 36
  • 49
  • Note, I also wondered if it doesn't accept all image formats. But I tried for jpg and png and neither worked. – durbachit Sep 20 '17 at 09:49
  • have you tried the same code as in your "instructions", i mean without a for loop with 2-3 images? Also, the video variable should be created only once, that means, outside the for. Also, I think you should release the video after using it (where the print is, outside the loop). One last thing you don't need to destroy all windows since there is none opened – api55 Sep 20 '17 at 11:45

1 Answers1

4

When you are running the for-loop, you are creating VideoWriters for every frame with same filename. Therefore it is over-writing the file with the new frame.
So, you have to create the VideoWriter object before entering the for-loop.

But doing that will not make your code working. There are some other errors due to misuse of commands.

First, os.listdir(path) will return list of filenames but not filepaths. Therefore you will need to add the folder path to that file name when you calling file read function (cv2.imread(imgPath+img)).

cv2.VideoWriter() will create the video file in the folder. Therefore it will also be listed in os.listdir(path). So you will need to remove files other than image files that you need. It can be done by checking the file extension.

After writing all the frames to the video, you will need to call the release() function to release the file handle.

And finally, makeVideo() function will not return anything. So there is no need to get it into a variable. (What you have to release() is file handler, but not the function as I said above).

Try the following code..

import cv2
import os

forexample = "C:/Users/me/Pictures/eg/"

eg = cv2.imread(forexample+'figure.jpg')
height , width , layers =  eg.shape

print("ok, got that ", height, " ", width, " ", layers)

def makeVideo(imgPath, videodir, videoname, width, height):
    video = cv2.VideoWriter(videodir+videoname,-1,1,(width, height))
    for img in os.listdir(imgPath):
        if not img.endswith('.jpg'):
            continue
        shot = cv2.imread(imgPath+img)
        video.write(shot)
    video.release()
    print("one video done")


makeVideo(forexample,forexample, "example.avi", width, height)

cv2.destroyAllWindows()
Ramesh-X
  • 4,853
  • 6
  • 46
  • 67
  • Some little progress: now the video is made, but can't be opened and it's size is 0 bytes... I am even prompted to define compression quality, but whatever I choose it makes no difference. – durbachit Sep 21 '17 at 00:55
  • This is getting ridiculous... I changed fourcc from -1 to 1 and got an error. Changed it back and now the video is produced, is 2.8 MB in size, but can't be opened. – durbachit Sep 21 '17 at 01:08
  • 1
    Here in the `VideoWriter`, -1 means no encoder is used. So you will be prompt to select the video encoder from the installed encoders in your system.
    And 1 means frame rate. So your images will be shown in the video, 1 image per second.
    So changing -1 and 1 will not solve the problem.
    May be you have no encoder installed in your system. Try installing codec pack.
    – Ramesh-X Sep 21 '17 at 08:18