From f1a3150ce9eb7493b57eac445cd1c2d7d1c65fd8 Mon Sep 17 00:00:00 2001 From: Colombo Date: Wed, 22 Jan 2020 22:14:31 +0400 Subject: [PATCH] 1 --- README.md | 4 ++ core/interact/interact.py | 20 +++++++++ mainscripts/Merger.py | 92 +++++++++++++++++++-------------------- merger/FrameInfo.py | 5 +-- merger/MergeMasked.py | 2 +- models/ModelBase.py | 2 + 6 files changed, 75 insertions(+), 50 deletions(-) diff --git a/README.md b/README.md index 81865f7..6462124 100644 --- a/README.md +++ b/README.md @@ -67,12 +67,16 @@ DeepFaceLab is used by such popular youtube channels as ||bitcoin:31mPd6DxPCzbpCMZk4k1koWAbErSyqkAXr|| |||| |Collect facesets|You can collect faceset of any celebrity that can be used in DeepFaceLab and share it [in the community](https://mrdeepfakes.com/forums/forum-celebrity-facesets)| + ## Meme zone

+ + + #deepfacelab #deepfakes #faceswap #face-swap #deep-learning #deeplearning #deep-neural-networks #deepface #deep-face-swap #fakeapp #fake-app #neural-networks #neural-nets diff --git a/core/interact/interact.py b/core/interact/interact.py index 46fd450..2f64cf4 100644 --- a/core/interact/interact.py +++ b/core/interact/interact.py @@ -367,6 +367,7 @@ class InteractBase(object): def input_in_time (self, str, max_time_sec): sq = multiprocessing.Queue() p = multiprocessing.Process(target=self.input_process, args=( sys.stdin.fileno(), sq, str)) + p.daemon = True p.start() t = time.time() inp = False @@ -380,6 +381,25 @@ class InteractBase(object): sys.stdin = os.fdopen( sys.stdin.fileno() ) return inp + def input_process_skip_pending(self, stdin_fd): + sys.stdin = os.fdopen(stdin_fd) + while True: + try: + if sys.stdin.isatty(): + sys.stdin.read() + except: + pass + + def input_skip_pending(self): + """ + skips unnecessary inputs between the dialogs + """ + p = multiprocessing.Process(target=self.input_process_skip_pending, args=( sys.stdin.fileno(), )) + p.daemon = True + p.start() + time.sleep(0.5) + p.terminate() + sys.stdin = os.fdopen( sys.stdin.fileno() ) class InteractDesktop(InteractBase): diff --git a/mainscripts/Merger.py b/mainscripts/Merger.py index ba6af29..bb0ce00 100644 --- a/mainscripts/Merger.py +++ b/mainscripts/Merger.py @@ -38,7 +38,7 @@ class MergeSubprocessor(Subprocessor): self.prev_temporal_frame_infos = prev_temporal_frame_infos self.frame_info = frame_info self.next_temporal_frame_infos = next_temporal_frame_infos - self.output_filename = None + self.output_filepath = None self.idx = None self.cfg = None @@ -53,14 +53,14 @@ class MergeSubprocessor(Subprocessor): prev_temporal_frame_infos=None, frame_info=None, next_temporal_frame_infos=None, - output_filename=None, + output_filepath=None, need_return_image = False): self.idx = idx self.cfg = cfg self.prev_temporal_frame_infos = prev_temporal_frame_infos self.frame_info = frame_info self.next_temporal_frame_infos = next_temporal_frame_infos - self.output_filename = output_filename + self.output_filepath = output_filepath self.need_return_image = need_return_image if self.need_return_image: @@ -124,34 +124,33 @@ class MergeSubprocessor(Subprocessor): frame_info = pf.frame_info - filename = frame_info.filename + filepath = frame_info.filepath landmarks_list = frame_info.landmarks_list - filename_path = Path(filename) - output_filename = pf.output_filename + output_filepath = pf.output_filepath need_return_image = pf.need_return_image if len(landmarks_list) == 0: - self.log_info ( 'no faces found for %s, copying without faces' % (filename_path.name) ) + self.log_info ( 'no faces found for %s, copying without faces' % (filepath.name) ) if cfg.export_mask_alpha: - img_bgr = cv2_imread(filename) + img_bgr = cv2_imread(filepath) h,w,c = img_bgr.shape if c == 1: img_bgr = np.repeat(img_bgr, 3, -1) if c == 3: img_bgr = np.concatenate ([img_bgr, np.zeros((h,w,1), dtype=img_bgr.dtype) ], axis=-1) - cv2_imwrite (output_filename, img_bgr) + cv2_imwrite (output_filepath, img_bgr) else: - if filename_path.suffix == '.png': - shutil.copy (filename, output_filename ) + if filepath.suffix == '.png': + shutil.copy ( str(filepath), str(output_filepath) ) else: - img_bgr = cv2_imread(filename) - cv2_imwrite (output_filename, img_bgr) + img_bgr = cv2_imread(filepath) + cv2_imwrite (output_filepath, img_bgr) if need_return_image: - img_bgr = cv2_imread(filename) + img_bgr = cv2_imread(filepath) pf.image = img_bgr else: if cfg.type == MergerConfig.TYPE_MASKED: @@ -165,7 +164,7 @@ class MergeSubprocessor(Subprocessor): if 'MemoryError' in e_str: raise Subprocessor.SilenceException else: - raise Exception( 'Error while merging file [%s]: %s' % (filename, e_str) ) + raise Exception( f'Error while merging file [{filepath}]: {e_str}' ) elif cfg.type == MergerConfig.TYPE_FACE_AVATAR: final_img = MergeFaceAvatar (self.predictor_func, self.predictor_input_shape, @@ -173,8 +172,8 @@ class MergeSubprocessor(Subprocessor): pf.frame_info, pf.next_temporal_frame_infos ) - if output_filename is not None and final_img is not None: - cv2_imwrite (output_filename, final_img ) + if output_filepath is not None and final_img is not None: + cv2_imwrite (output_filepath, final_img ) if need_return_image: pf.image = final_img @@ -184,10 +183,10 @@ class MergeSubprocessor(Subprocessor): #overridable def get_data_name (self, pf): #return string identificator of your data - return pf.frame_info.filename + return pf.frame_info.filepath #override - def __init__(self, is_interactive, merger_session_filepath, predictor_func, predictor_input_shape, merger_config, frames, output_path, model_iter): + def __init__(self, is_interactive, merger_session_filepath, predictor_func, predictor_input_shape, merger_config, frames, frames_root_path, output_path, model_iter): if len (frames) == 0: raise ValueError ("len (frames) == 0") @@ -225,6 +224,7 @@ class MergeSubprocessor(Subprocessor): self.fanseg_host, self.fanseg_extract_func = SubprocessFunctionCaller.make_pair(fanseg_extract_func) + self.frames_root_path = frames_root_path self.output_path = output_path self.model_iter = model_iter @@ -232,11 +232,12 @@ class MergeSubprocessor(Subprocessor): session_data = None if self.is_interactive and self.merger_session_filepath.exists(): - + io.input_skip_pending() if io.input_bool ("Use saved session?", True): try: with open( str(self.merger_session_filepath), "rb") as f: session_data = pickle.loads(f.read()) + except Exception as e: pass @@ -245,6 +246,7 @@ class MergeSubprocessor(Subprocessor): self.frames_done_idxs = [] if self.is_interactive and session_data is not None: + # Loaded session data, check it s_frames = session_data.get('frames', None) s_frames_idxs = session_data.get('frames_idxs', None) s_frames_done_idxs = session_data.get('frames_done_idxs', None) @@ -254,13 +256,14 @@ class MergeSubprocessor(Subprocessor): (s_frames_idxs is not None) and \ (s_frames_done_idxs is not None) and \ (s_model_iter is not None) and \ - (len(frames) == len(s_frames)) + (len(frames) == len(s_frames)) # frames count must match if frames_equal: for i in range(len(frames)): frame = frames[i] s_frame = s_frames[i] - if frame.frame_info.filename != s_frame.frame_info.filename: + # frames filenames must match + if frame.frame_info.filepath.name != s_frame.frame_info.filepath.name: frames_equal = False if not frames_equal: break @@ -270,25 +273,23 @@ class MergeSubprocessor(Subprocessor): for frame in s_frames: if frame.cfg is not None: - #recreate MergerConfig class using constructor with get_config() as dict params - #so if any new param will be added, old merger session will work properly + # recreate MergerConfig class using constructor with get_config() as dict params + # so if any new param will be added, old merger session will work properly frame.cfg = frame.cfg.__class__( **frame.cfg.get_config() ) self.frames = s_frames self.frames_idxs = s_frames_idxs self.frames_done_idxs = s_frames_done_idxs - - - if self.model_iter != s_model_iter: - #model is more trained, recompute all frames + rewind_to_begin = len(self.frames_idxs) == 0 # all frames are done? + + if self.model_iter != s_model_iter: + # model was more trained, recompute all frames + rewind_to_begin = True for frame in self.frames: frame.is_done = False - if self.model_iter != s_model_iter or \ - len(self.frames_idxs) == 0: - #rewind to begin if model is more trained or all frames are done - + if rewind_to_begin: while len(self.frames_done_idxs) > 0: prev_frame = self.frames[self.frames_done_idxs.pop()] self.frames_idxs.insert(0, prev_frame.idx) @@ -309,9 +310,7 @@ class MergeSubprocessor(Subprocessor): for i in range( len(self.frames) ): frame = self.frames[i] frame.idx = i - frame.output_filename = self.output_path / ( Path(frame.frame_info.filename).stem + '.png' ) - - + frame.output_filepath = self.output_path / ( frame.frame_info.filepath.stem + '.png' ) #override def process_info_generator(self): @@ -330,7 +329,7 @@ class MergeSubprocessor(Subprocessor): #overridable optional def on_clients_initialized(self): - io.progress_bar ("Merging", len (self.frames_idxs), initial=len(self.frames_done_idxs) ) + io.progress_bar ("Merging", len(self.frames_idxs)+len(self.frames_done_idxs), initial=len(self.frames_done_idxs) ) self.process_remain_frames = not self.is_interactive self.is_interactive_quitting = not self.is_interactive @@ -393,7 +392,7 @@ class MergeSubprocessor(Subprocessor): self.screen_manager.finalize() for frame in self.frames: - frame.output_filename = None + frame.output_filepath = None frame.image = None session_data = { @@ -433,10 +432,10 @@ class MergeSubprocessor(Subprocessor): if not cur_frame.is_shown: if cur_frame.is_done: cur_frame.is_shown = True - io.log_info (cur_frame.cfg.to_string( cur_frame.frame_info.filename_short) ) + io.log_info (cur_frame.cfg.to_string( cur_frame.frame_info.filepath.name) ) if cur_frame.image is None: - cur_frame.image = cv2_imread ( cur_frame.output_filename) + cur_frame.image = cv2_imread ( cur_frame.output_filepath) if cur_frame.image is None: # unable to read? recompute then cur_frame.is_done = False @@ -474,7 +473,7 @@ class MergeSubprocessor(Subprocessor): self.masked_keys_funcs[chr_key](cfg, shift_pressed) if prev_cfg != cfg: - io.log_info ( cfg.to_string(cur_frame.frame_info.filename_short) ) + io.log_info ( cfg.to_string(cur_frame.frame_info.filepath.name) ) cur_frame.is_done = False cur_frame.is_shown = False else: @@ -607,7 +606,7 @@ class MergeSubprocessor(Subprocessor): prev_temporal_frame_infos=frame.prev_temporal_frame_infos, frame_info=frame.frame_info, next_temporal_frame_infos=frame.next_temporal_frame_infos, - output_filename=frame.output_filename, + output_filepath=frame.output_filepath, need_return_image=True ) return None @@ -705,7 +704,7 @@ def main (model_class_name=None, if multiple_faces_detected: io.log_info ("Warning: multiple faces detected. Strongly recommended to process them separately.") - frames = [ MergeSubprocessor.Frame( frame_info=FrameInfo(filename=p, landmarks_list=alignments.get(Path(p).stem, None))) for p in input_path_image_paths ] + frames = [ MergeSubprocessor.Frame( frame_info=FrameInfo(filepath=Path(p), landmarks_list=alignments.get(Path(p).stem, None))) for p in input_path_image_paths ] if multiple_faces_detected: io.log_info ("Warning: multiple faces detected. Motion blur will not be used.") @@ -750,9 +749,9 @@ def main (model_class_name=None, if dflimg is None: io.log_err ("%s is not a dfl image file" % (filepath.name) ) continue - filesdata += [ ( FrameInfo(filename=str(filepath), landmarks_list=[dflimg.get_landmarks()] ), dflimg.get_source_filename() ) ] + filesdata += [ ( FrameInfo(filepath=filepath, landmarks_list=[dflimg.get_landmarks()] ), dflimg.get_source_filename() ) ] - filesdata = sorted(filesdata, key=operator.itemgetter(1)) #sort by filename + filesdata = sorted(filesdata, key=operator.itemgetter(1)) #sort by source_filename frames = [] filesdata_len = len(filesdata) for i in range(len(filesdata)): @@ -776,12 +775,13 @@ def main (model_class_name=None, io.log_info ("No frames to merge in input_dir.") else: MergeSubprocessor ( - is_interactive = is_interactive, + is_interactive = is_interactive, merger_session_filepath = merger_session_filepath, predictor_func = predictor_func, predictor_input_shape = predictor_input_shape, - merger_config = cfg, + merger_config = cfg, frames = frames, + frames_root_path = input_path, output_path = output_path, model_iter = model.get_iter() ).run() diff --git a/merger/FrameInfo.py b/merger/FrameInfo.py index a6d21a3..1b8ebb0 100644 --- a/merger/FrameInfo.py +++ b/merger/FrameInfo.py @@ -1,9 +1,8 @@ from pathlib import Path class FrameInfo(object): - def __init__(self, filename=None, landmarks_list=None): - self.filename = filename - self.filename_short = str(Path(filename).name) + def __init__(self, filepath=None, landmarks_list=None): + self.filepath = filepath self.landmarks_list = landmarks_list or [] self.motion_deg = 0 self.motion_power = 0 \ No newline at end of file diff --git a/merger/MergeMasked.py b/merger/MergeMasked.py index 8aa3067..453ea0d 100644 --- a/merger/MergeMasked.py +++ b/merger/MergeMasked.py @@ -334,7 +334,7 @@ def MergeMaskedFace (predictor_func, predictor_input_shape, cfg, frame_info, img def MergeMasked (predictor_func, predictor_input_shape, cfg, frame_info): - img_bgr_uint8 = cv2_imread(frame_info.filename) + img_bgr_uint8 = cv2_imread(frame_info.filepath) img_bgr_uint8 = imagelib.normalize_channels (img_bgr_uint8, 3) img_bgr = img_bgr_uint8.astype(np.float32) / 255.0 diff --git a/models/ModelBase.py b/models/ModelBase.py index 1b43099..5bb1024 100644 --- a/models/ModelBase.py +++ b/models/ModelBase.py @@ -158,6 +158,8 @@ class ModelBase(object): self.batch_size = self.load_or_def_option('batch_size', 1) ##### + io.input_skip_pending() + self.on_initialize_options() if self.is_first_run(): # save as default options only for first run model initialize