Skip to content
This repository was archived by the owner on May 30, 2024. It is now read-only.

Commit 5ec91f3

Browse files
refactor
1 parent dc8f4f1 commit 5ec91f3

File tree

2 files changed

+65
-66
lines changed

2 files changed

+65
-66
lines changed

t2v.py

+25-26
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,6 @@
1414
'BLACK': [[255, 255, 255], [0, 0, 0]]
1515
}
1616

17-
parser = argparse.ArgumentParser(
18-
description='This program converts text to videos.')
19-
20-
parser.add_argument('input', type=str, help='input text file')
21-
parser.add_argument('output', type=str, help='output video')
22-
parser.add_argument('-W', '--width', type=int, help='output video width')
23-
parser.add_argument('-H', '--height', type=int, help='output video height')
24-
parser.add_argument('-F', '--fps', type=int, help='FPS of output video')
25-
parser.add_argument('-A', '--audio', type=str, help='input audio file')
26-
parser.add_argument('-f', '--font', type=str, help='font path', required=True)
27-
2817

2918
def getDisplayMode(mode):
3019
if mode not in DISPLAY_MODE:
@@ -33,35 +22,50 @@ def getDisplayMode(mode):
3322
return DISPLAY_MODE[mode]
3423

3524

36-
def textToFrame(data):
25+
def _textToFrame(data):
3726
text = data[0]
3827
opts = data[1]
39-
# print(os.getpid())
28+
return textToFrame(text, **opts)
29+
4030

31+
def textToFrame(text, font, output_height, output_width, height, width):
4132
monospace = cv2.freetype.createFreeType2()
4233
monospace.loadFontData(
43-
fontFileName=opts['font'], id=0)
44-
fontHeight = opts['output_height'] // opts['height']
34+
fontFileName=font, id=0)
35+
fontHeight = output_height // height
4536
textSize, baseline = monospace.getTextSize(
46-
text='a'*opts['width'], fontHeight=fontHeight, thickness=-1)
47-
region = (textSize[0], fontHeight*opts['height'])
37+
text='a'*width, fontHeight=fontHeight, thickness=-1)
38+
region = (fontHeight*height, textSize[0])
4839

4940
mode, rendertext = text.split('\n', 1)
5041
colors = getDisplayMode(mode)
5142

52-
frame = np.full((*reversed(region), 3), colors[1], dtype=np.uint8)
43+
frame = np.full((*region, 3), colors[1], dtype=np.uint8)
5344

5445
for i, line in enumerate(text.split('\n')):
5546
monospace.putText(img=frame, text=line, org=(0, i*fontHeight),
5647
fontHeight=fontHeight, color=colors[0], thickness=-1, line_type=cv2.LINE_4, bottomLeftOrigin=True)
5748

5849
frame = cv2.resize(frame, dsize=(
59-
opts['output_width'], opts['output_height']))
50+
output_width, output_height))
6051
# cv2.imwrite('test/{:04}.png'.format(ind), frame)
6152
return frame
6253

6354

64-
def main():
55+
if __name__ == "__main__":
56+
parser = argparse.ArgumentParser(
57+
description='This program converts text to videos.')
58+
59+
parser.add_argument('input', type=str, help='input text file')
60+
parser.add_argument('output', type=str, help='output video')
61+
parser.add_argument('-W', '--width', type=int, help='output video width')
62+
parser.add_argument('-H', '--height', type=int, help='output video height')
63+
parser.add_argument('-F', '--fps', type=int, help='FPS of output video')
64+
parser.add_argument('-A', '--audio', type=str, help='input audio file')
65+
parser.add_argument('-f', '--font', type=str,
66+
help='font path', required=True)
67+
args = parser.parse_args()
68+
6569
with open(args.input) as f:
6670
fp = next(itertools.islice(csv.DictReader(
6771
[f.readline(), f.readline()]), 1))
@@ -110,7 +114,7 @@ def main():
110114
with mp.Pool(mp.cpu_count()) as pool:
111115
with tqdm(total=len(texts)) as t:
112116
for res in pool.imap(
113-
textToFrame, zip(texts, repeat(opts))):
117+
_textToFrame, zip(texts, repeat(opts))):
114118
t.update()
115119
out.write(res)
116120

@@ -121,8 +125,3 @@ def main():
121125
audio = ffmpeg.input(args.audio)
122126
ffmpeg.output(audio.audio, video.video,
123127
args.output, shortest=None).run()
124-
125-
126-
if __name__ == "__main__":
127-
args = parser.parse_args()
128-
main()

v2t.py

+40-40
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
import ffmpeg
1313
import re
1414

15+
global N
16+
global N_WIDTH
17+
global N_HEIGHT
18+
global THRESHOLD
19+
1520
N = 16
1621
N_WIDTH = N//2
1722
N_HEIGHT = N
@@ -20,16 +25,6 @@
2025
CHARS = ['W', '#', 'R', 'E', '8', 'x', 's', 'i', ';', ',', '.', ' ']
2126
PALETTE = np.arange(len(CHARS))
2227

23-
parser = argparse.ArgumentParser(
24-
description='This program converts videos to texts.')
25-
26-
parser.add_argument('input', help='input video')
27-
parser.add_argument('output', help='output text')
28-
parser.add_argument('-s', '--size', type=int)
29-
parser.add_argument('-m', '--mode', type=str, help='choose WHITE or BLACK')
30-
parser.add_argument('-t', '--threshold', type=int,
31-
help='threshold between white and black')
32-
3328

3429
def cover_multiple(current_length, multiple):
3530
"""
@@ -54,58 +49,68 @@ def slicer(a, chunk_i, chunk_j, two_d=True):
5449
return c
5550

5651

57-
def frameToText(frame, opts):
52+
def frameToText(frame, chars, palette, n_height, n_width, mode=None, threshold=110):
5853
text = ''
5954

6055
frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
61-
if not opts['mode']:
62-
if frame_gray.mean() < opts['THRESHOLD']:
56+
if mode is None:
57+
if frame_gray.mean() < threshold:
6358
text = 'BLACK\n'
64-
chars = np.array(list(reversed(opts['CHARS'])), dtype='<U1')
59+
chars = np.array(list(reversed(chars)), dtype='<U1')
6560
else:
6661
text = 'WHITE\n'
67-
chars = np.array(opts['CHARS'], dtype='<U1')
62+
chars = np.array(chars, dtype='<U1')
6863
else:
69-
if opts['mode'] == 'WHITE':
64+
if mode == 'WHITE':
7065
text = 'WHITE\n'
71-
chars = np.array(opts['CHARS'], dtype='<U1')
66+
chars = np.array(chars, dtype='<U1')
7267
else:
7368
text = 'BLACK\n'
74-
chars = np.array(list(reversed(opts['CHARS'])), dtype='<U1')
69+
chars = np.array(list(reversed(chars)), dtype='<U1')
7570

7671
tmp = np.nanmean(
77-
slicer(frame_gray, opts['N_HEIGHT'], opts['N_WIDTH']), axis=(2, 3))
72+
slicer(frame_gray, n_height, n_width), axis=(2, 3))
7873
tmp = tmp / 256 * len(chars)
7974
tmp = tmp.astype(int)
80-
ind = np.digitize(tmp.ravel(), opts['PALETTE'], right=True)
75+
ind = np.digitize(tmp.ravel(), PALETTE, right=True)
8176
tmp2 = ''.join(chars[ind].tolist())
82-
chunk_size = ceil(frame_gray.shape[1]/opts['N_WIDTH'])
77+
chunk_size = ceil(frame_gray.shape[1]/n_width)
8378

8479
tmp3 = [tmp2[i:i+chunk_size] for i in range(0, len(tmp2), chunk_size)]
8580

8681
text += '\n'.join(tmp3)
8782
return text
8883

8984

90-
def loadFrame(path):
91-
return cv2.imread(path)
85+
def loadFrame(bytes):
86+
return cv2.imdecode(np.fromstring(bytes, dtype='uint8'), cv2.IMREAD_UNCHANGED)
9287

9388

94-
def loadFrameAndConvertToText(data):
89+
def loadFrameFileAndConvertToText(data):
9590
path = data[0]
9691
opts = data[1]
97-
return frameToText(loadFrame(path), opts)
92+
with open(path, 'rb') as f:
93+
return frameToText(loadFrame(f.read()), **opts)
94+
95+
96+
if __name__ == "__main__":
97+
parser = argparse.ArgumentParser(
98+
description='This program converts videos to texts.')
9899

100+
parser.add_argument('input', help='input video')
101+
parser.add_argument('output', help='output text')
102+
parser.add_argument('-s', '--size', type=int)
103+
parser.add_argument('-m', '--mode', type=str, help='choose WHITE or BLACK')
104+
parser.add_argument('-t', '--threshold', type=int,
105+
help='threshold between white and black')
106+
107+
args = parser.parse_args()
99108

100-
def main(args):
101109
if args.size:
102-
global N
103110
N = args.size
104111
if args.threshold:
105-
global THRESHOLD
106112
THRESHOLD = args.threshold
107113

108-
global N_WIDTH, N_HEIGHT
109114
N_WIDTH = N//2
110115
N_HEIGHT = N
111116

@@ -114,11 +119,11 @@ def main(args):
114119

115120
texts = []
116121
opts = {}
117-
opts['THRESHOLD'] = THRESHOLD
118-
opts['CHARS'] = CHARS
119-
opts['N_HEIGHT'] = N_HEIGHT
120-
opts['N_WIDTH'] = N_WIDTH
121-
opts['PALETTE'] = PALETTE
122+
opts['threshold'] = THRESHOLD
123+
opts['chars'] = CHARS
124+
opts['n_height'] = N_HEIGHT
125+
opts['n_width'] = N_WIDTH
126+
opts['palette'] = PALETTE
122127
opts['mode'] = args.mode
123128

124129
with tempfile.TemporaryDirectory() as tmpdir:
@@ -128,7 +133,7 @@ def main(args):
128133
files.sort(key=lambda f: int(re.sub('\D', '', f)))
129134
with mp.Pool(mp.cpu_count()) as pool:
130135
with tqdm(total=len(files)) as t:
131-
for res in pool.imap(loadFrameAndConvertToText, zip(list(map(lambda f: os.path.join(tmpdir, f), files)), repeat(opts))):
136+
for res in pool.imap(loadFrameFileAndConvertToText, zip(list(map(lambda f: os.path.join(tmpdir, f), files)), repeat(opts))):
132137
texts.append(res)
133138
t.update()
134139

@@ -148,8 +153,3 @@ def main(args):
148153
filepath, fps, int(width), int(height), origwidth, origheight))
149154
f.write('=====\n')
150155
f.write('\n'.join(texts))
151-
152-
153-
if __name__ == "__main__":
154-
args = parser.parse_args()
155-
main(args)

0 commit comments

Comments
 (0)