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:
- Fetch all the image file names using glob
- Read all the images using cv2.imread()
- Store all the images into a list
- Create a VideoWriter object using cv2.VideoWriter()
- Save the images to video file using cv2.VideoWriter().write()
- Release the VideoWriter and destroy all windows.
Let’s see the code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import cv2 import numpy as np import glob img_array = [] for filename in glob.glob('C:/New folder/Images/*.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'), 15, size) for i in range(len(img_array)): out.write(img_array[i]) out.release() |
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.
I get the video but the frames are order randomly, how can I arrange them in a sequential order? thanks for the post
For this, you have to arrange images in the desired order in the image folder manually.
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
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.
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.
files.sort() will sort alpha numerically (1 10 11 2 20 21). If you want ‘natural’ sorting like 1 2 10 11 etc.. Follow this link https://stackoverflow.com/questions/4623446/how-do-you-sort-files-numerically
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()
images are getting without waiting time and also it is not taking horizontal images
Hey, I m getting an error saying no module named cv2.
wht shud i do?
please reply
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
install the package
!pip install cv2
or
!pip install opencv
it to slow when i play
Try changing the FPS from 15 to some higher value in the following line:
its showing an error none type object has no attribute release
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.
and sorry about the format i just don’t know how to fancy display the code part. :/
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.
Sure you can comment your problem here or you can directly write to TheAILearner at contact us page and we will be happy to help you: https://theailearner.com/contact-us/
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 ?
Hi, This means that the image is not loaded. Try checking if the image path you gave is correct or not.
Yes indeed ! Thanks
how can you add some text a title for instance to the movie is this easy to do?
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()
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
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.
How to set the length of the video?
Hi the output video lasts only 1 second and i have 10 images in folder. how can I make video last longer. thanks
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.
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 !!
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
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.
Can i add some animations when image change to other in video?
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
video blink in middle of video with black screen in every secend.
how to add background audio ?
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
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