-
Notifications
You must be signed in to change notification settings - Fork 0
/
encode.py
102 lines (81 loc) · 2.58 KB
/
encode.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
import time
import pylab
import imageio
import skimage.transform
HEIGHT = 64
WIDTH = 128
FPS = 25
filename = 'bad_apple_25.mp4'
video = imageio.get_reader(filename, 'ffmpeg')
print("loading video frames")
video_frames = []
for i in range(1_000_000):
try:
video_frames.append(video.get_data(i))
except IndexError:
break
print(f"loaded {len(video_frames)} video frames")
def get_frame(f):
frame = video_frames[f]
frame = skimage.transform.resize(frame, (HEIGHT, WIDTH))
# for y in range(HEIGHT):
# for x in range(WIDTH):
# print('#' if frame[y, x][0] > 0.5 else ' ', end='')
# print('')
# print('\n')
# print('\n')
return frame
# fig = pylab.figure()
# fig.suptitle('image', fontsize=20)
# pylab.imshow(get_frame(100))
# pylab.show()
def encode_image(img):
result = []
for x in range(0, WIDTH, 8):
for y in range(0, HEIGHT, 8):
for yi in range(8):
v = 0
for xi in range(8):
v = (v << 1) | (1 if img[y + yi, x + xi][0] > 0.5 else 0)
# (x * 8 + y) * 8 + i
result.append(v)
return result
def encode_video(frame_indices):
data = []
last = None
for frame_counter, frame_index in enumerate(frame_indices):
frame = encode_image(get_frame(frame_index))
if len(data) == 0:
print("processed first frame")
# 255 = full frame
data.append(255)
data += frame
last = frame
continue
changes_frame = []
# print("changes frame:")
for i in range(0, len(last), 8):
for j in range(8):
if last[i + j] != frame[i + j]:
break
else:
continue
changes_frame.append(i // 8)
for j in range(8):
changes_frame.append(frame[i + j])
print(f"processed frame {frame_counter}/{len(frame_indices)}")
if len(changes_frame) < len(frame):
print("using changes frame", len(changes_frame) // 9)
data.append(len(changes_frame) // 9)
data += changes_frame
else:
print("using full frame")
data.append(255)
data += frame
last = frame
print(f"total compression: {len(data) / (len(frame_indices) * 8 * (WIDTH // 8) * (HEIGHT // 8))}")
return data
if __name__ == '__main__':
result_bytes = bytearray(encode_video(range(0, len(video_frames), 1)))
with open(filename + ".bin", "wb") as f:
f.write(result_bytes)