-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmain.py
214 lines (171 loc) · 7.68 KB
/
main.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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
import argparse
import os
from face_processor import face_processor
import numpy as np
from skimage.viewer import ImageViewer
import progressbar
import skvideo.io
import skimage.io
import multiprocessing as mp
def process_video(worker_no, fp, bar, files, landmarks, out_files, queue, rate, window_size):
# Worker loop
while True:
task = queue.get()
if task is not None:
try:
new_video, projected_landmarks = fp.normalise_face(files[task], landmarks[task],
window_size=window_size)
except Exception as e:
print("Exception Handled: ", e)
print(files[task])
queue.task_done()
continue
if new_video is None:
queue.task_done()
continue
cropped_video = new_video[:, :crop_height, :crop_width, :]
vid_out = skvideo.io.FFmpegWriter(out_files[task], inputdict={'-r': rate, }, outputdict={'-r': rate, })
for frame_no in range(cropped_video.shape[0]):
vid_out.writeFrame(cropped_video[frame_no])
vid_out.close()
queue.task_done()
else:
break
# Only the first worker updates the progress
if worker_no == 0:
bar.update(task)
queue.task_done()
def swap_extension(file, ext):
return os.path.splitext(file)[0] + ext
parser = argparse.ArgumentParser()
parser.add_argument("--scale", type=float, help="the file extension for the video", default=1.0)
parser.add_argument("--smoothing_window", "-w", type=int, help="The window to use for smoothing", default=7)
parser.add_argument("--file_list", "-f", nargs='?', help="The file list")
parser.add_argument("--offset", nargs='+', type=float, help="offsets the mean face")
parser.add_argument("--input", "-i", help="folder containing input videos")
parser.add_argument("--landmarks", "-l", help="folder containing landmarks")
parser.add_argument("--output", "-o", help="folder containing output videos")
parser.add_argument("--subjects", "-s", nargs='+', help="the specific subjects to obtain")
parser.add_argument("--mean", "-m", nargs='?', help="gets the mean face")
parser.add_argument("--calculate_mean", "-c", action='store_true', help="gets the mean face", default=False)
parser.add_argument("--gpu", "-g", action='store_true', help="uses the gpu for face alignment", default=False)
parser.add_argument("--visualise", "-v", nargs='?', help="visualises the landmarks")
parser.add_argument("--ext_video", help="the file extension for the video")
parser.add_argument("--append_extension", "-a", help="path to append after subject")
parser.add_argument("--add_extension", action='store_true', help="appends extension to files", default=False)
parser.add_argument("--picture", "-p", action='store_true', help="processes images", default=False)
parser.add_argument("--append_folder", action='store_true', help="appends input folder to files", default=False)
parser.add_argument("--reference", "-r", help="reference image")
parser.add_argument("--workers", type=int, help="number of workers to use")
parser.add_argument("--out_size", nargs='+', type=int, help="offsets the mean face")
args = parser.parse_args()
mean_face = None
reference = None
no_workers = mp.cpu_count()
if args.workers is not None:
no_workers = min(args.workers, mp.cpu_count())
if args.append_extension is None:
extension = "/"
else:
extension = "/" + args.append_extension + "/"
if args.visualise is not None:
mean_face = np.load(args.visualise)
if args.offset is not None:
face_processor.offset_mean_face(mean_face, offset_percentage=args.offset[:2])
tl_corner, br_corner = face_processor.find_corners(mean_face)
canvas = np.zeros([br_corner[1], br_corner[0], 3]).astype(np.uint8)
face_processor.draw_points(canvas, mean_face, tag=True, in_place=True)
viewer = ImageViewer(canvas)
viewer.show()
exit(0)
if args.mean is not None:
mean_face = args.scale * np.load(args.mean)
height_border = 0
width_border = 0
if args.offset is not None:
mean_face = face_processor.offset_mean_face(mean_face, offset_percentage=args.offset[:2])
height_border += args.offset[1] + args.offset[2]
width_border += 2 * args.offset[0]
if args.out_size is not None:
crop_height = args.out_size[0]
crop_width = args.out_size[1]
elif args.reference is not None:
reference = skimage.io.imread(args.reference)
crop_height = reference.shape[0]
crop_width = reference.shape[1]
else:
face_width, face_height = face_processor.get_width_height(mean_face)
crop_height = int(face_height * (1 + height_border))
crop_width = int(face_width * (1 + width_border))
print("Size will be W: " + str(crop_width) + " H: " + str(crop_height))
fp = face_processor(cuda=args.gpu, mean_face=mean_face, ref_img=args.reference, img_size=(crop_height, crop_width))
if args.picture:
pictures = os.listdir(args.input)
if not os.path.exists(args.output):
os.makedirs(args.output)
for picture in pictures:
img = skimage.io.imread(args.input + "/" + picture)
warped_img = fp.process_image(img)
if warped_img is not None:
skimage.io.imsave(args.output + "/" + picture, warped_img[:crop_height, :crop_width, :])
exit()
if args.subjects is None and args.file_list is None:
subject_folder_list = os.listdir(args.input)
elif args.file_list is None:
subject_folder_list = [str(s) for s in args.subjects]
files = []
out_files = []
landmarks = []
queue = mp.JoinableQueue()
progress = 0
if args.file_list is None:
for subject_folder in subject_folder_list:
if not os.path.exists(args.output + "/" + subject_folder):
os.makedirs(args.output + "/" + subject_folder)
for video_file in os.listdir(args.input + "/" + subject_folder + extension):
if args.ext_video is not None and not video_file.endswith(args.ext_video):
continue
files.append(args.input + "/" + subject_folder + extension + video_file)
if args.landmarks is None:
landmarks.append(None)
else:
landmarks.append(args.landmarks + "/" + subject_folder + extension + swap_extension(video_file, ".csv"))
out_files.append(args.output + "/" + subject_folder + "/" + video_file)
queue.put(progress)
progress += 1
else:
fh = open(args.file_list, "r")
files = fh.readlines()
added_ext = ""
if args.add_extension:
added_ext = args.ext_video
if args.append_folder:
files = [args.input + "/" + f.rstrip('\n') + added_ext for f in files]
for i, f in enumerate(files):
landmarks.append(f.replace(args.input, args.landmarks).replace(args.ext_video, ".csv"))
out_path = f.replace(args.input, args.output)
out_folder = os.path.dirname(os.path.abspath(out_path))
if not os.path.exists(out_folder):
os.makedirs(out_folder)
out_files.append(out_path)
queue.put(i)
fh.close()
if args.calculate_mean:
mean_face = fp.find_mean_face(files)
np.save("mean_face.npy", mean_face)
bar = progressbar.ProgressBar(max_value=len(files)).start()
rate = face_processor.get_frame_rate(files[0])
workers = []
for i in range(no_workers):
queue.put(None) # Place the poison pills for the workers
for i in range(no_workers):
workers.append(mp.Process(target=process_video,
args=((i, fp, bar, files, landmarks, out_files, queue, rate, args.smoothing_window))))
for worker in workers:
worker.start()
try:
queue.join()
except KeyboardInterrupt:
for worker in workers:
worker.terminate()
bar.finish()