|
import imageio, os |
|
import numpy as np |
|
from PIL import Image |
|
|
|
|
|
def read_video(file_name): |
|
reader = imageio.get_reader(file_name) |
|
video = [] |
|
for frame in reader: |
|
frame = np.array(frame) |
|
video.append(frame) |
|
reader.close() |
|
return video |
|
|
|
|
|
def get_video_fps(file_name): |
|
reader = imageio.get_reader(file_name) |
|
fps = reader.get_meta_data()["fps"] |
|
reader.close() |
|
return fps |
|
|
|
|
|
def save_video(frames_path, video_path, num_frames, fps): |
|
writer = imageio.get_writer(video_path, fps=fps, quality=9) |
|
for i in range(num_frames): |
|
frame = np.array(Image.open(os.path.join(frames_path, "%05d.png" % i))) |
|
writer.append_data(frame) |
|
writer.close() |
|
return video_path |
|
|
|
|
|
class LowMemoryVideo: |
|
def __init__(self, file_name): |
|
self.reader = imageio.get_reader(file_name) |
|
|
|
def __len__(self): |
|
return self.reader.count_frames() |
|
|
|
def __getitem__(self, item): |
|
return np.array(self.reader.get_data(item)) |
|
|
|
def __del__(self): |
|
self.reader.close() |
|
|
|
|
|
def split_file_name(file_name): |
|
result = [] |
|
number = -1 |
|
for i in file_name: |
|
if ord(i)>=ord("0") and ord(i)<=ord("9"): |
|
if number == -1: |
|
number = 0 |
|
number = number*10 + ord(i) - ord("0") |
|
else: |
|
if number != -1: |
|
result.append(number) |
|
number = -1 |
|
result.append(i) |
|
if number != -1: |
|
result.append(number) |
|
result = tuple(result) |
|
return result |
|
|
|
|
|
def search_for_images(folder): |
|
file_list = [i for i in os.listdir(folder) if i.endswith(".jpg") or i.endswith(".png")] |
|
file_list = [(split_file_name(file_name), file_name) for file_name in file_list] |
|
file_list = [i[1] for i in sorted(file_list)] |
|
file_list = [os.path.join(folder, i) for i in file_list] |
|
return file_list |
|
|
|
|
|
def read_images(folder): |
|
file_list = search_for_images(folder) |
|
frames = [np.array(Image.open(i)) for i in file_list] |
|
return frames |
|
|
|
|
|
class LowMemoryImageFolder: |
|
def __init__(self, folder, file_list=None): |
|
if file_list is None: |
|
self.file_list = search_for_images(folder) |
|
else: |
|
self.file_list = [os.path.join(folder, file_name) for file_name in file_list] |
|
|
|
def __len__(self): |
|
return len(self.file_list) |
|
|
|
def __getitem__(self, item): |
|
return np.array(Image.open(self.file_list[item])) |
|
|
|
def __del__(self): |
|
pass |
|
|
|
|
|
class VideoData: |
|
def __init__(self, video_file, image_folder, **kwargs): |
|
if video_file is not None: |
|
self.data_type = "video" |
|
self.data = LowMemoryVideo(video_file, **kwargs) |
|
elif image_folder is not None: |
|
self.data_type = "images" |
|
self.data = LowMemoryImageFolder(image_folder, **kwargs) |
|
else: |
|
raise ValueError("Cannot open video or image folder") |
|
self.length = None |
|
self.height = None |
|
self.width = None |
|
|
|
def raw_data(self): |
|
frames = [] |
|
for i in range(self.__len__()): |
|
frames.append(self.__getitem__(i)) |
|
return frames |
|
|
|
def set_length(self, length): |
|
self.length = length |
|
|
|
def set_shape(self, height, width): |
|
self.height = height |
|
self.width = width |
|
|
|
def __len__(self): |
|
if self.length is None: |
|
return len(self.data) |
|
else: |
|
return self.length |
|
|
|
def shape(self): |
|
if self.height is not None and self.width is not None: |
|
return self.height, self.width |
|
else: |
|
height, width, _ = self.__getitem__(0).shape |
|
return height, width |
|
|
|
def __getitem__(self, item): |
|
frame = self.data.__getitem__(item) |
|
height, width, _ = frame.shape |
|
if self.height is not None and self.width is not None: |
|
if self.height != height or self.width != width: |
|
frame = Image.fromarray(frame).resize((self.width, self.height)) |
|
frame = np.array(frame) |
|
return frame |
|
|
|
def __del__(self): |
|
pass |
|
|