Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
iperov
GitHub Repository: iperov/deepfacelab
Path: blob/master/mainscripts/dev_misc.py
628 views
1
import traceback
2
import json
3
import multiprocessing
4
import shutil
5
from pathlib import Path
6
import cv2
7
import numpy as np
8
9
from core import imagelib, pathex
10
from core.cv2ex import *
11
from core.interact import interact as io
12
from core.joblib import Subprocessor
13
from core.leras import nn
14
from DFLIMG import *
15
from facelib import FaceType, LandmarksProcessor
16
from . import Extractor, Sorter
17
from .Extractor import ExtractSubprocessor
18
19
20
def extract_vggface2_dataset(input_dir, device_args={} ):
21
multi_gpu = device_args.get('multi_gpu', False)
22
cpu_only = device_args.get('cpu_only', False)
23
24
input_path = Path(input_dir)
25
if not input_path.exists():
26
raise ValueError('Input directory not found. Please ensure it exists.')
27
28
bb_csv = input_path / 'loose_bb_train.csv'
29
if not bb_csv.exists():
30
raise ValueError('loose_bb_train.csv found. Please ensure it exists.')
31
32
bb_lines = bb_csv.read_text().split('\n')
33
bb_lines.pop(0)
34
35
bb_dict = {}
36
for line in bb_lines:
37
name, l, t, w, h = line.split(',')
38
name = name[1:-1]
39
l, t, w, h = [ int(x) for x in (l, t, w, h) ]
40
bb_dict[name] = (l,t,w, h)
41
42
43
output_path = input_path.parent / (input_path.name + '_out')
44
45
dir_names = pathex.get_all_dir_names(input_path)
46
47
if not output_path.exists():
48
output_path.mkdir(parents=True, exist_ok=True)
49
50
data = []
51
for dir_name in io.progress_bar_generator(dir_names, "Collecting"):
52
cur_input_path = input_path / dir_name
53
cur_output_path = output_path / dir_name
54
55
if not cur_output_path.exists():
56
cur_output_path.mkdir(parents=True, exist_ok=True)
57
58
input_path_image_paths = pathex.get_image_paths(cur_input_path)
59
60
for filename in input_path_image_paths:
61
filename_path = Path(filename)
62
63
name = filename_path.parent.name + '/' + filename_path.stem
64
if name not in bb_dict:
65
continue
66
67
l,t,w,h = bb_dict[name]
68
if min(w,h) < 128:
69
continue
70
71
data += [ ExtractSubprocessor.Data(filename=filename,rects=[ (l,t,l+w,t+h) ], landmarks_accurate=False, force_output_path=cur_output_path ) ]
72
73
face_type = FaceType.fromString('full_face')
74
75
io.log_info ('Performing 2nd pass...')
76
data = ExtractSubprocessor (data, 'landmarks', 256, face_type, debug_dir=None, multi_gpu=multi_gpu, cpu_only=cpu_only, manual=False).run()
77
78
io.log_info ('Performing 3rd pass...')
79
ExtractSubprocessor (data, 'final', 256, face_type, debug_dir=None, multi_gpu=multi_gpu, cpu_only=cpu_only, manual=False, final_output_path=None).run()
80
81
82
"""
83
import code
84
code.interact(local=dict(globals(), **locals()))
85
86
data_len = len(data)
87
i = 0
88
while i < data_len-1:
89
i_name = Path(data[i].filename).parent.name
90
91
sub_data = []
92
93
for j in range (i, data_len):
94
j_name = Path(data[j].filename).parent.name
95
if i_name == j_name:
96
sub_data += [ data[j] ]
97
else:
98
break
99
i = j
100
101
cur_output_path = output_path / i_name
102
103
io.log_info (f"Processing: {str(cur_output_path)}, {i}/{data_len} ")
104
105
if not cur_output_path.exists():
106
cur_output_path.mkdir(parents=True, exist_ok=True)
107
108
109
110
111
112
113
114
115
for dir_name in dir_names:
116
117
cur_input_path = input_path / dir_name
118
cur_output_path = output_path / dir_name
119
120
input_path_image_paths = pathex.get_image_paths(cur_input_path)
121
l = len(input_path_image_paths)
122
#if l < 250 or l > 350:
123
# continue
124
125
io.log_info (f"Processing: {str(cur_input_path)} ")
126
127
if not cur_output_path.exists():
128
cur_output_path.mkdir(parents=True, exist_ok=True)
129
130
131
data = []
132
for filename in input_path_image_paths:
133
filename_path = Path(filename)
134
135
name = filename_path.parent.name + '/' + filename_path.stem
136
if name not in bb_dict:
137
continue
138
139
bb = bb_dict[name]
140
l,t,w,h = bb
141
if min(w,h) < 128:
142
continue
143
144
data += [ ExtractSubprocessor.Data(filename=filename,rects=[ (l,t,l+w,t+h) ], landmarks_accurate=False ) ]
145
146
147
148
io.log_info ('Performing 2nd pass...')
149
data = ExtractSubprocessor (data, 'landmarks', 256, face_type, debug_dir=None, multi_gpu=False, cpu_only=False, manual=False).run()
150
151
io.log_info ('Performing 3rd pass...')
152
data = ExtractSubprocessor (data, 'final', 256, face_type, debug_dir=None, multi_gpu=False, cpu_only=False, manual=False, final_output_path=cur_output_path).run()
153
154
155
io.log_info (f"Sorting: {str(cur_output_path)} ")
156
Sorter.main (input_path=str(cur_output_path), sort_by_method='hist')
157
158
import code
159
code.interact(local=dict(globals(), **locals()))
160
161
#try:
162
# io.log_info (f"Removing: {str(cur_input_path)} ")
163
# shutil.rmtree(cur_input_path)
164
#except:
165
# io.log_info (f"unable to remove: {str(cur_input_path)} ")
166
167
168
169
170
def extract_vggface2_dataset(input_dir, device_args={} ):
171
multi_gpu = device_args.get('multi_gpu', False)
172
cpu_only = device_args.get('cpu_only', False)
173
174
input_path = Path(input_dir)
175
if not input_path.exists():
176
raise ValueError('Input directory not found. Please ensure it exists.')
177
178
output_path = input_path.parent / (input_path.name + '_out')
179
180
dir_names = pathex.get_all_dir_names(input_path)
181
182
if not output_path.exists():
183
output_path.mkdir(parents=True, exist_ok=True)
184
185
186
187
for dir_name in dir_names:
188
189
cur_input_path = input_path / dir_name
190
cur_output_path = output_path / dir_name
191
192
l = len(pathex.get_image_paths(cur_input_path))
193
if l < 250 or l > 350:
194
continue
195
196
io.log_info (f"Processing: {str(cur_input_path)} ")
197
198
if not cur_output_path.exists():
199
cur_output_path.mkdir(parents=True, exist_ok=True)
200
201
Extractor.main( str(cur_input_path),
202
str(cur_output_path),
203
detector='s3fd',
204
image_size=256,
205
face_type='full_face',
206
max_faces_from_image=1,
207
device_args=device_args )
208
209
io.log_info (f"Sorting: {str(cur_input_path)} ")
210
Sorter.main (input_path=str(cur_output_path), sort_by_method='hist')
211
212
try:
213
io.log_info (f"Removing: {str(cur_input_path)} ")
214
shutil.rmtree(cur_input_path)
215
except:
216
io.log_info (f"unable to remove: {str(cur_input_path)} ")
217
218
"""
219
220
#unused in end user workflow
221
def dev_test_68(input_dir ):
222
# process 68 landmarks dataset with .pts files
223
input_path = Path(input_dir)
224
if not input_path.exists():
225
raise ValueError('input_dir not found. Please ensure it exists.')
226
227
output_path = input_path.parent / (input_path.name+'_aligned')
228
229
io.log_info(f'Output dir is % {output_path}')
230
231
if output_path.exists():
232
output_images_paths = pathex.get_image_paths(output_path)
233
if len(output_images_paths) > 0:
234
io.input_bool("WARNING !!! \n %s contains files! \n They will be deleted. \n Press enter to continue." % (str(output_path)), False )
235
for filename in output_images_paths:
236
Path(filename).unlink()
237
else:
238
output_path.mkdir(parents=True, exist_ok=True)
239
240
images_paths = pathex.get_image_paths(input_path)
241
242
for filepath in io.progress_bar_generator(images_paths, "Processing"):
243
filepath = Path(filepath)
244
245
246
pts_filepath = filepath.parent / (filepath.stem+'.pts')
247
if pts_filepath.exists():
248
pts = pts_filepath.read_text()
249
pts_lines = pts.split('\n')
250
251
lmrk_lines = None
252
for pts_line in pts_lines:
253
if pts_line == '{':
254
lmrk_lines = []
255
elif pts_line == '}':
256
break
257
else:
258
if lmrk_lines is not None:
259
lmrk_lines.append (pts_line)
260
261
if lmrk_lines is not None and len(lmrk_lines) == 68:
262
try:
263
lmrks = [ np.array ( lmrk_line.strip().split(' ') ).astype(np.float32).tolist() for lmrk_line in lmrk_lines]
264
except Exception as e:
265
print(e)
266
print(filepath)
267
continue
268
269
rect = LandmarksProcessor.get_rect_from_landmarks(lmrks)
270
271
output_filepath = output_path / (filepath.stem+'.jpg')
272
273
img = cv2_imread(filepath)
274
img = imagelib.normalize_channels(img, 3)
275
cv2_imwrite(output_filepath, img, [int(cv2.IMWRITE_JPEG_QUALITY), 95] )
276
277
raise Exception("unimplemented")
278
#DFLJPG.x(output_filepath, face_type=FaceType.toString(FaceType.MARK_ONLY),
279
# landmarks=lmrks,
280
# source_filename=filepath.name,
281
# source_rect=rect,
282
# source_landmarks=lmrks
283
# )
284
285
io.log_info("Done.")
286
287
#unused in end user workflow
288
def extract_umd_csv(input_file_csv,
289
face_type='full_face',
290
device_args={} ):
291
292
#extract faces from umdfaces.io dataset csv file with pitch,yaw,roll info.
293
multi_gpu = device_args.get('multi_gpu', False)
294
cpu_only = device_args.get('cpu_only', False)
295
face_type = FaceType.fromString(face_type)
296
297
input_file_csv_path = Path(input_file_csv)
298
if not input_file_csv_path.exists():
299
raise ValueError('input_file_csv not found. Please ensure it exists.')
300
301
input_file_csv_root_path = input_file_csv_path.parent
302
output_path = input_file_csv_path.parent / ('aligned_' + input_file_csv_path.name)
303
304
io.log_info("Output dir is %s." % (str(output_path)) )
305
306
if output_path.exists():
307
output_images_paths = pathex.get_image_paths(output_path)
308
if len(output_images_paths) > 0:
309
io.input_bool("WARNING !!! \n %s contains files! \n They will be deleted. \n Press enter to continue." % (str(output_path)), False )
310
for filename in output_images_paths:
311
Path(filename).unlink()
312
else:
313
output_path.mkdir(parents=True, exist_ok=True)
314
315
try:
316
with open( str(input_file_csv_path), 'r') as f:
317
csv_file = f.read()
318
except Exception as e:
319
io.log_err("Unable to open or read file " + str(input_file_csv_path) + ": " + str(e) )
320
return
321
322
strings = csv_file.split('\n')
323
keys = strings[0].split(',')
324
keys_len = len(keys)
325
csv_data = []
326
for i in range(1, len(strings)):
327
values = strings[i].split(',')
328
if keys_len != len(values):
329
io.log_err("Wrong string in csv file, skipping.")
330
continue
331
332
csv_data += [ { keys[n] : values[n] for n in range(keys_len) } ]
333
334
data = []
335
for d in csv_data:
336
filename = input_file_csv_root_path / d['FILE']
337
338
339
x,y,w,h = float(d['FACE_X']), float(d['FACE_Y']), float(d['FACE_WIDTH']), float(d['FACE_HEIGHT'])
340
341
data += [ ExtractSubprocessor.Data(filename=filename, rects=[ [x,y,x+w,y+h] ]) ]
342
343
images_found = len(data)
344
faces_detected = 0
345
if len(data) > 0:
346
io.log_info ("Performing 2nd pass from csv file...")
347
data = ExtractSubprocessor (data, 'landmarks', multi_gpu=multi_gpu, cpu_only=cpu_only).run()
348
349
io.log_info ('Performing 3rd pass...')
350
data = ExtractSubprocessor (data, 'final', face_type, None, multi_gpu=multi_gpu, cpu_only=cpu_only, manual=False, final_output_path=output_path).run()
351
faces_detected += sum([d.faces_detected for d in data])
352
353
354
io.log_info ('-------------------------')
355
io.log_info ('Images found: %d' % (images_found) )
356
io.log_info ('Faces detected: %d' % (faces_detected) )
357
io.log_info ('-------------------------')
358
359
360
361
def dev_test1(input_dir):
362
# LaPa dataset
363
364
image_size = 1024
365
face_type = FaceType.HEAD
366
367
input_path = Path(input_dir)
368
images_path = input_path / 'images'
369
if not images_path.exists:
370
raise ValueError('LaPa dataset: images folder not found.')
371
labels_path = input_path / 'labels'
372
if not labels_path.exists:
373
raise ValueError('LaPa dataset: labels folder not found.')
374
landmarks_path = input_path / 'landmarks'
375
if not landmarks_path.exists:
376
raise ValueError('LaPa dataset: landmarks folder not found.')
377
378
output_path = input_path / 'out'
379
if output_path.exists():
380
output_images_paths = pathex.get_image_paths(output_path)
381
if len(output_images_paths) != 0:
382
io.input(f"\n WARNING !!! \n {output_path} contains files! \n They will be deleted. \n Press enter to continue.\n")
383
for filename in output_images_paths:
384
Path(filename).unlink()
385
output_path.mkdir(parents=True, exist_ok=True)
386
387
data = []
388
389
img_paths = pathex.get_image_paths (images_path)
390
for filename in img_paths:
391
filepath = Path(filename)
392
393
landmark_filepath = landmarks_path / (filepath.stem + '.txt')
394
if not landmark_filepath.exists():
395
raise ValueError(f'no landmarks for {filepath}')
396
397
#img = cv2_imread(filepath)
398
399
lm = landmark_filepath.read_text()
400
lm = lm.split('\n')
401
if int(lm[0]) != 106:
402
raise ValueError(f'wrong landmarks format in {landmark_filepath}')
403
404
lmrks = []
405
for i in range(106):
406
x,y = lm[i+1].split(' ')
407
x,y = float(x), float(y)
408
lmrks.append ( (x,y) )
409
410
lmrks = np.array(lmrks)
411
412
l,t = np.min(lmrks, 0)
413
r,b = np.max(lmrks, 0)
414
415
l,t,r,b = ( int(x) for x in (l,t,r,b) )
416
417
#for x, y in lmrks:
418
# x,y = int(x), int(y)
419
# cv2.circle(img, (x, y), 1, (0,255,0) , 1, lineType=cv2.LINE_AA)
420
421
#imagelib.draw_rect(img, (l,t,r,b), (0,255,0) )
422
423
424
data += [ ExtractSubprocessor.Data(filepath=filepath, rects=[ (l,t,r,b) ]) ]
425
426
#cv2.imshow("", img)
427
#cv2.waitKey(0)
428
429
if len(data) > 0:
430
device_config = nn.DeviceConfig.BestGPU()
431
432
io.log_info ("Performing 2nd pass...")
433
data = ExtractSubprocessor (data, 'landmarks', image_size, 95, face_type, device_config=device_config).run()
434
io.log_info ("Performing 3rd pass...")
435
data = ExtractSubprocessor (data, 'final', image_size, 95, face_type, final_output_path=output_path, device_config=device_config).run()
436
437
438
for filename in pathex.get_image_paths (output_path):
439
filepath = Path(filename)
440
441
442
dflimg = DFLJPG.load(filepath)
443
444
src_filename = dflimg.get_source_filename()
445
image_to_face_mat = dflimg.get_image_to_face_mat()
446
447
label_filepath = labels_path / ( Path(src_filename).stem + '.png')
448
if not label_filepath.exists():
449
raise ValueError(f'{label_filepath} does not exist')
450
451
mask = cv2_imread(label_filepath)
452
#mask[mask == 10] = 0 # remove hair
453
mask[mask > 0] = 1
454
mask = cv2.warpAffine(mask, image_to_face_mat, (image_size, image_size), cv2.INTER_LINEAR)
455
mask = cv2.blur(mask, (3,3) )
456
457
#cv2.imshow("", (mask*255).astype(np.uint8) )
458
#cv2.waitKey(0)
459
460
dflimg.set_xseg_mask(mask)
461
dflimg.save()
462
463
464
import code
465
code.interact(local=dict(globals(), **locals()))
466
467
468
def dev_resave_pngs(input_dir):
469
input_path = Path(input_dir)
470
if not input_path.exists():
471
raise ValueError('input_dir not found. Please ensure it exists.')
472
473
images_paths = pathex.get_image_paths(input_path, image_extensions=['.png'], subdirs=True, return_Path_class=True)
474
475
for filepath in io.progress_bar_generator(images_paths,"Processing"):
476
cv2_imwrite(filepath, cv2_imread(filepath))
477
478
479
def dev_segmented_trash(input_dir):
480
input_path = Path(input_dir)
481
if not input_path.exists():
482
raise ValueError('input_dir not found. Please ensure it exists.')
483
484
output_path = input_path.parent / (input_path.name+'_trash')
485
output_path.mkdir(parents=True, exist_ok=True)
486
487
images_paths = pathex.get_image_paths(input_path, return_Path_class=True)
488
489
trash_paths = []
490
for filepath in images_paths:
491
json_file = filepath.parent / (filepath.stem +'.json')
492
if not json_file.exists():
493
trash_paths.append(filepath)
494
495
for filepath in trash_paths:
496
497
try:
498
filepath.rename ( output_path / filepath.name )
499
except:
500
io.log_info ('fail to trashing %s' % (src.name) )
501
502
503
504
def dev_test(input_dir):
505
"""
506
extract FaceSynthetics dataset https://github.com/microsoft/FaceSynthetics
507
508
BACKGROUND = 0
509
SKIN = 1
510
NOSE = 2
511
RIGHT_EYE = 3
512
LEFT_EYE = 4
513
RIGHT_BROW = 5
514
LEFT_BROW = 6
515
RIGHT_EAR = 7
516
LEFT_EAR = 8
517
MOUTH_INTERIOR = 9
518
TOP_LIP = 10
519
BOTTOM_LIP = 11
520
NECK = 12
521
HAIR = 13
522
BEARD = 14
523
CLOTHING = 15
524
GLASSES = 16
525
HEADWEAR = 17
526
FACEWEAR = 18
527
IGNORE = 255
528
"""
529
530
531
image_size = 1024
532
face_type = FaceType.WHOLE_FACE
533
534
input_path = Path(input_dir)
535
536
537
538
output_path = input_path.parent / f'{input_path.name}_out'
539
if output_path.exists():
540
output_images_paths = pathex.get_image_paths(output_path)
541
if len(output_images_paths) != 0:
542
io.input(f"\n WARNING !!! \n {output_path} contains files! \n They will be deleted. \n Press enter to continue.\n")
543
for filename in output_images_paths:
544
Path(filename).unlink()
545
output_path.mkdir(parents=True, exist_ok=True)
546
547
data = []
548
549
for filepath in io.progress_bar_generator(pathex.get_paths(input_path), "Processing"):
550
if filepath.suffix == '.txt':
551
552
image_filepath = filepath.parent / f'{filepath.name.split("_")[0]}.png'
553
if not image_filepath.exists():
554
print(f'{image_filepath} does not exist, skipping')
555
556
lmrks = []
557
for lmrk_line in filepath.read_text().split('\n'):
558
if len(lmrk_line) == 0:
559
continue
560
561
x, y = lmrk_line.split(' ')
562
x, y = float(x), float(y)
563
564
lmrks.append( (x,y) )
565
566
lmrks = np.array(lmrks[:68], np.float32)
567
rect = LandmarksProcessor.get_rect_from_landmarks(lmrks)
568
data += [ ExtractSubprocessor.Data(filepath=image_filepath, rects=[rect], landmarks=[ lmrks ] ) ]
569
570
if len(data) > 0:
571
io.log_info ("Performing 3rd pass...")
572
data = ExtractSubprocessor (data, 'final', image_size, 95, face_type, final_output_path=output_path, device_config=nn.DeviceConfig.CPU()).run()
573
574
for filename in io.progress_bar_generator(pathex.get_image_paths (output_path), "Processing"):
575
filepath = Path(filename)
576
577
dflimg = DFLJPG.load(filepath)
578
579
src_filename = dflimg.get_source_filename()
580
image_to_face_mat = dflimg.get_image_to_face_mat()
581
582
seg_filepath = input_path / ( Path(src_filename).stem + '_seg.png')
583
if not seg_filepath.exists():
584
raise ValueError(f'{seg_filepath} does not exist')
585
586
seg = cv2_imread(seg_filepath)
587
seg_inds = np.isin(seg, [1,2,3,4,5,6,9,10,11])
588
seg[~seg_inds] = 0
589
seg[seg_inds] = 1
590
seg = seg.astype(np.float32)
591
seg = cv2.warpAffine(seg, image_to_face_mat, (image_size, image_size), cv2.INTER_LANCZOS4)
592
dflimg.set_xseg_mask(seg)
593
dflimg.save()
594
595