Spaces:
Build error
Build error
Helper functions
Browse files- helpers/__init__.py +0 -0
- helpers/image.py +50 -0
- helpers/video.py +39 -0
helpers/__init__.py
ADDED
File without changes
|
helpers/image.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import requests
|
3 |
+
import numpy as np
|
4 |
+
|
5 |
+
def image_grid(imgs, rows, cols):
|
6 |
+
assert len(imgs) == rows*cols
|
7 |
+
|
8 |
+
w, h = imgs[0].size
|
9 |
+
grid = Image.new('RGB', size=(cols*w, rows*h))
|
10 |
+
grid_w, grid_h = grid.size
|
11 |
+
|
12 |
+
for i, img in enumerate(imgs):
|
13 |
+
grid.paste(img, box=(i%cols*w, i//cols*h))
|
14 |
+
return grid
|
15 |
+
|
16 |
+
def shrink_and_paste_on_blank(current_image, mask_width):
|
17 |
+
"""
|
18 |
+
Decreases size of current_image by mask_width pixels from each side,
|
19 |
+
then adds a mask_width width transparent frame,
|
20 |
+
so that the image the function returns is the same size as the input.
|
21 |
+
:param current_image: input image to transform
|
22 |
+
:param mask_width: width in pixels to shrink from each side
|
23 |
+
"""
|
24 |
+
|
25 |
+
height = current_image.height
|
26 |
+
width = current_image.width
|
27 |
+
|
28 |
+
#shrink down by mask_width
|
29 |
+
prev_image = current_image.resize((height-2*mask_width,width-2*mask_width))
|
30 |
+
prev_image = prev_image.convert("RGBA")
|
31 |
+
prev_image = np.array(prev_image)
|
32 |
+
|
33 |
+
#create blank non-transparent image
|
34 |
+
blank_image = np.array(current_image.convert("RGBA"))*0
|
35 |
+
blank_image[:,:,3] = 1
|
36 |
+
|
37 |
+
#paste shrinked onto blank
|
38 |
+
blank_image[mask_width:height-mask_width,mask_width:width-mask_width,:] = prev_image
|
39 |
+
prev_image = Image.fromarray(blank_image)
|
40 |
+
|
41 |
+
return prev_image
|
42 |
+
|
43 |
+
def load_img(address, res=(512, 512)):
|
44 |
+
if address.startswith('http://') or address.startswith('https://'):
|
45 |
+
image = Image.open(requests.get(address, stream=True).raw)
|
46 |
+
else:
|
47 |
+
image = Image.open(address)
|
48 |
+
image = image.convert('RGB')
|
49 |
+
image = image.resize(res, resample=Image.LANCZOS)
|
50 |
+
return image
|
helpers/video.py
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
|
4 |
+
|
5 |
+
def write_video(file_path, frames, fps, reversed=True, start_frame_dupe_amount=15, last_frame_dupe_amount=30):
|
6 |
+
"""
|
7 |
+
Writes frames to an mp4 video file
|
8 |
+
:param file_path: Path to output video, must end with .mp4
|
9 |
+
:param frames: List of PIL.Image objects
|
10 |
+
:param fps: Desired frame rate
|
11 |
+
:param reversed: if order of images to be reversed (default = True)
|
12 |
+
"""
|
13 |
+
if reversed == True:
|
14 |
+
frames.reverse()
|
15 |
+
|
16 |
+
w, h = frames[0].size
|
17 |
+
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
|
18 |
+
# fourcc = cv2.VideoWriter_fourcc('h', '2', '6', '4')
|
19 |
+
# fourcc = cv2.VideoWriter_fourcc(*'avc1')
|
20 |
+
writer = cv2.VideoWriter(file_path, fourcc, fps, (w, h))
|
21 |
+
|
22 |
+
# start frame duplicated
|
23 |
+
for x in range(start_frame_dupe_amount):
|
24 |
+
np_frame = np.array(frames[0].convert('RGB'))
|
25 |
+
cv_frame = cv2.cvtColor(np_frame, cv2.COLOR_RGB2BGR)
|
26 |
+
writer.write(cv_frame)
|
27 |
+
|
28 |
+
for frame in frames:
|
29 |
+
np_frame = np.array(frame.convert('RGB'))
|
30 |
+
cv_frame = cv2.cvtColor(np_frame, cv2.COLOR_RGB2BGR)
|
31 |
+
writer.write(cv_frame)
|
32 |
+
|
33 |
+
# last frame duplicated
|
34 |
+
for x in range(last_frame_dupe_amount):
|
35 |
+
np_frame = np.array(frames[len(frames) - 1].convert('RGB'))
|
36 |
+
cv_frame = cv2.cvtColor(np_frame, cv2.COLOR_RGB2BGR)
|
37 |
+
writer.write(cv_frame)
|
38 |
+
|
39 |
+
writer.release()
|