-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathImageSequenceClip.py
171 lines (116 loc) · 5.13 KB
/
ImageSequenceClip.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import os
import numpy as np
from imageio import imread
from moviepy.video.VideoClip import VideoClip
""" Modification in file: In `venv/lib/python3.6/site-packages/moviepy/video/io/ImageSequenceClip.py`, line70:
Before: `if isinstance(sequence, list):`
After: `if isinstance(sequence, list) or isinstance(sequence, np.ndarray)`
"""
class ImageSequenceClip(VideoClip):
"""
A VideoClip made from a series of images.
Parameters
-----------
sequence
Can be one of these:
- The name of a folder (containing only pictures). The pictures
will be considered in alphanumerical order.
- A list of names of image files. In this case you can choose to
load the pictures in memory pictures
- A list of Numpy arrays representing images. In this last case,
masks are not supported currently.
fps
Number of picture frames to read per second. Instead, you can provide
the duration of each image with durations (see below)
durations
List of the duration of each picture.
with_mask
Should the alpha layer of PNG images be considered as a mask ?
ismask
Will this sequence of pictures be used as an animated mask.
Notes
------
If your sequence is made of image files, the only image kept in
"""
def __init__(self, sequence, fps=None, durations=None, with_mask=True,
ismask=False, load_images=False):
# CODE WRITTEN AS IT CAME, MAY BE IMPROVED IN THE FUTURE
if (fps is None) and (durations is None):
raise ValueError("Please provide either 'fps' or 'durations'.")
VideoClip.__init__(self, ismask=ismask)
# Parse the data
fromfiles = True
if isinstance(sequence, list) or isinstance(sequence, np.ndarray):
if isinstance(sequence[0], str):
if load_images:
sequence = [imread(f) for f in sequence]
fromfiles = False
else:
fromfiles= True
else:
# sequence is already a list of numpy arrays
fromfiles = False
else:
# sequence is a folder name, make it a list of files:
fromfiles = True
sequence = sorted([os.path.join(sequence, f)
for f in os.listdir(sequence)])
#check that all the images are of the same size
if isinstance(sequence[0], str):
size = imread(sequence[0]).shape
else:
size = sequence[0].shape
for image in sequence:
image1=image
if isinstance(image, str):
image1=imread(image)
if size != image1.shape:
raise Exception("Moviepy: ImageSequenceClip requires all images to be the same size")
self.fps = fps
if fps is not None:
durations = [1.0/fps for image in sequence]
self.images_starts = [1.0*i/fps-np.finfo(np.float32).eps for i in range(len(sequence))]
else:
self.images_starts = [0]+list(np.cumsum(durations))
self.durations = durations
self.duration = sum(durations)
self.end = self.duration
self.sequence = sequence
def find_image_index(t):
return max([i for i in range(len(self.sequence))
if self.images_starts[i]<=t])
if fromfiles:
self.lastindex = None
self.lastimage = None
def make_frame(t):
index = find_image_index(t)
if index != self.lastindex:
self.lastimage = imread(self.sequence[index])[:,:,:3]
self.lastindex = index
return self.lastimage
if with_mask and (imread(self.sequence[0]).shape[2]==4):
self.mask = VideoClip(ismask=True)
self.mask.lastindex = None
self.mask.lastimage = None
def mask_make_frame(t):
index = find_image_index(t)
if index != self.mask.lastindex:
frame = imread(self.sequence[index])[:,:,3]
self.mask.lastimage = frame.astype(float)/255
self.mask.lastindex = index
return self.mask.lastimage
self.mask.make_frame = mask_make_frame
self.mask.size = mask_make_frame(0).shape[:2][::-1]
else:
def make_frame(t):
index = find_image_index(t)
return self.sequence[index][:,:,:3]
if with_mask and (self.sequence[0].shape[2]==4):
self.mask = VideoClip(ismask=True)
def mask_make_frame(t):
index = find_image_index(t)
return 1.0*self.sequence[index][:,:,3]/255
self.mask.make_frame = mask_make_frame
self.mask.size = mask_make_frame(0).shape[:2][::-1]
self.make_frame = make_frame
self.size = make_frame(0).shape[:2][::-1]