Creating Video from Images using OpenCV-Python

In this blog, we will do a small project using OpenCV-Python where we will be creating video from image sequences. This project is entirely based on what we read in Chapter 1 and 2. Let’s start

Steps:

  1.  Fetch all the image file names using glob
  2.  Read all the images using cv2.imread()
  3.  Store all the images into a list
  4.  Create a VideoWriter object using cv2.VideoWriter()
  5.  Save the images to video file using cv2.VideoWriter().write()
  6.  Release the VideoWriter and destroy all windows.

Let’s see the code

glob.glob(Pathname) fetches all the filenames present in that path. ‘*.jpg’ means all the jpg files. So, in code glob.glob() fetches the filename of all the jpg files present in that path.

Hope you enjoy reading.

If you have any doubt/suggestion please feel free to ask and I will do my best to help or improve myself. Good-bye until next time.

43 thoughts on “Creating Video from Images using OpenCV-Python

  1. Rodrigo Silva

    I get the video but the frames are order randomly, how can I arrange them in a sequential order? thanks for the post

    Reply
    1. faraz

      img_array = []
      for count in range(len(os.listdir(path))):

      filename = ‘./path/mask_frame_’ + str(count) + ‘.jpg’
      img = cv2.imread(filename)
      height, width, layers = img.shape
      size = (width,height)
      img_array.append(img)

      out = cv2.VideoWriter(‘project.avi’,cv2.VideoWriter_fourcc(*’DIVX’), 24, size)

      for i in range(len(img_array)):
      out.write(img_array[i])
      out.release()
      ””””””””””””””””””””””””””’
      copy paste this code to run in your own oath of images

      Reply
    2. Arpan Khandelwal

      It seems that by default, it doesn’t matter what name you provide to the images or how you will arrange them, it reads them in descending order of size.

      Reply
      1. Victor Meunier

        If your images are ordered with some kind of number like im_1, im_2, etc.. Just do : files.sort(). Where files is your list of files.

        Reply
      2. Tranks

        Sorting worked. Thanks. Here’s implementation.

        import cv2
        import numpy as np
        import glob

        video_name = ‘video3.avi’

        file_list = []
        img_array = []
        for filename in glob.glob(‘png/*.png’):
        file_list.append(filename)

        file_list.sort()

        for i in file_list:
        frame = cv2.imread(i)
        height, width, layers = frame.shape
        frame_size = (width,height)
        img_array.append(frame)

        video = cv2.VideoWriter(video_name, cv2.VideoWriter_fourcc(*’DIVX’), 15, frame_size)
        for i in range(len(img_array)):
        video.write(img_array[i])

        cv2.destroyAllWindows()
        video.release()

        Reply
    1. kang & atul Post author

      First you need to install opencv. For that you can use pip command as follows:
      “pip install opencv-python”
      or you can download it’s whl file from here and then install using pip.
      “pip install whl_file_name”
      For more details please follow this blog

      Reply
  2. theailea

    Try changing the FPS from 15 to some higher value in the following line:

    Reply
  3. Tehseen .Akhtar

    Hi Guys..!!
    Well it is late but still i thought i would share the code i used for this purpose and without the sorting algo. Although i don’t well know about its efficiency as i am still new to python so any corrections are welcomed:

    import cv2

    img_array = []

    for x in range (0,20):
    img = cv2.imread(‘C:/New folder/Images/Img_{0}.jpg’.format(x))
    height, width, layers = img.shape
    size = (width, height)
    img_array.append (img)

    out = cv2.VideoWriter (‘project.avi’, cv2.VideoWriter_fourcc (*’DIVX’), 15, size)

    for i in range (len (img_array)):
    out.write (img_array[i])
    out.release ()

    So basically i have a directory where i have this 20 images named Img_00.JPG to Img_19.JPG. So it will automatically read the images in the order from 0 to 19. Or in any order we want we just need to use the for loop accordingly. Hope this helps someone.

    Reply
    1. Tehseen .Akhtar

      and sorry about the format i just don’t know how to fancy display the code part. :/

      Reply
  4. Arindam Ganguly

    Hi, Need an help on the same. It’s not working for all the JPEG images, please let me know some way to connect with you.

    Reply
  5. Sébastien

    Hi,

    I really need your help.
    I’m trying to use this code in Jupyter Notebook to make a video with 7 images whi are in png. Their names are :
    0.png
    1.png
    2.png

    6.png

    And here the code :

    import cv2

    img_array = []

    for x in range (0,6):
    img = cv2.imread(‘C:/Users/test/{0}.png’.format(x))
    height, width, layers = img.shape
    size = (width, height)
    img_array.append (img)

    out = cv2.VideoWriter (‘project.avi’, cv2.VideoWriter_fourcc (*’DIVX’), 15, size)

    for i in range (len (img_array)):
    out.write (img_array[i])
    out.release ()

    But I have always the same error,

    AttributeError Traceback (most recent call last)
    in
    5 for x in range (0,6):
    6 img = cv2.imread(‘C:/Users/sszollosi/Documents/Conference_SIG/SIG2019/Démo_IA/Road_cracks/code_Rohit/arcgis-tf-roaddamagedetector/arcgis-tf-roaddamagedetector/test/{0}.png’.format(x))
    —-> 7 height, width, layers = img.shape
    8 size = (width, height)
    9 img_array.append (img)

    AttributeError: ‘NoneType’ object has no attribute ‘shape’

    any idea why ?

    Reply
  6. Lisa Søndergaard

    Hello!
    I continue getting an error regarding image-size:

    Traceback (most recent call last):
    File “video-tool-c.py”, line 14, in
    out = cv2.VideoWriter(‘film_test.api’,cv2.VideoWriter_fourcc(*’DIVX’), 16, size)
    NameError: name ‘size’ is not defined

    I haven’t been able to fix it. Does someone have an idea what could be wrong?
    My code looks like this:

    import cv2
    import numpy as np
    import glob

    img_array = []
    for filename in glob.glob(‘C:/bill*.png’):
    img = cv2.imread(filename)
    height, width, layers = img.shape
    size = (width, height)
    img_array.append(img)

    out = cv2.VideoWriter(‘film_test.api’,cv2.VideoWriter_fourcc(*’DIVX’), 16, size)

    for i in range(len(img_array)):
    out.write(img_array[i])
    out.release()

    Reply
    1. kang & atul Post author

      Hi Lisa… This may be because of the for loop not executing. Try checking the path or printing the size inside the for loop. Hope this helps

      Reply
  7. Jaydeep Godbole

    Why create a list of image frames and then write them to the video generator later? These two can both be done at the same time. Read the image and then write it instantly. Thus, the memory required for the image array can be saved.

    Reply
  8. Peter

    Hi the output video lasts only 1 second and i have 10 images in folder. how can I make video last longer. thanks

    Reply
    1. kang & atul Post author

      Hi, Peter
      Thanks for reading the post. To make the video longer you need to adjust the frame per second (fps) argument in the cv2.Videowriter() function (Line 13 in the above code).
      Change the value 15 to 1 or any other lower number (0.5 etc) according to your problem.
      Hope this helps.

      Reply
      1. moaz

        I have the same problem but I have 50 images and all of them are loaded and changed the fps to 1 but the video length isn’t 50 seconds !!

        Reply
  9. Peter

    Thanks for your quick reply. It worked perfectly. The problem I’m having is that not all images in folder are included in video. It seems that only images with the same size are included. Other images are ignored. How could I modify the code to include all images.

    Could you please tell me what are these two lines of code doing:
    height, width, layers = img.shape
    size = (width, height)

    Thanks

    Reply
    1. kang & atul Post author

      Hi, Peter
      Yes, only images with the size equivalent to your last image will be included in the video. This is because of the write() method (Line 16).
      This method only includes the images that have the same size as has been specified when opening the video writer (the size in Line 13). That’s the reason you are facing the problem.
      To solve this you must resize all the images to some fixed size. For that, you can use OpenCV’s cv2.resize() function after reading the image (Line 7).

      Second, these two code lines are simply used for setting the size of the output video. If you already know the size of your image files, you can skip these two lines and manually pass the size (e.g (1200,720)) in the cv2.Videowriter() method (Line 13). Again this code assumes all the image files are of the same size.

      Hope this helps. Thanks.

      Reply
  10. kesly

    Hello,
    I would like to save the video in a server, how can i get the video to binary mode without saving it in my directory ?

    Thank you

    Reply
  11. pavan

    it’s working for small size folders.
    when i am giving large size folder my system was hanging.
    is there any code for handle the large size of image folder

    Reply
  12. Jad Hariri

    Hello, I need help for a little thing I have to create a python script that compress a video. What I did is to separate the frames of the video compress frame bi
    Y frame then use videoWriter, the only problem is that the compressed video take more memory than the old video even though the compressed images that I used to create the video are smaller what can be the source of this problem ?
    Thank you

    Reply

Leave a Reply