diff --git a/core/cv2ex.py b/core/cv2ex.py index ea6ca84..17c8095 100644 --- a/core/cv2ex.py +++ b/core/cv2ex.py @@ -4,7 +4,7 @@ from pathlib import Path from core.interact import interact as io import traceback -def cv2_imread(filename, flags=cv2.IMREAD_UNCHANGED, loader_func=None): +def cv2_imread(filename, flags=cv2.IMREAD_UNCHANGED, loader_func=None, verbose=True): """ allows to open non-english characters path """ @@ -17,7 +17,8 @@ def cv2_imread(filename, flags=cv2.IMREAD_UNCHANGED, loader_func=None): numpyarray = np.asarray(bytes, dtype=np.uint8) return cv2.imdecode(numpyarray, flags) except: - io.log_err(f"Exception occured in cv2_imread : {traceback.format_exc()}") + if verbose: + io.log_err(f"Exception occured in cv2_imread : {traceback.format_exc()}") return None def cv2_imwrite(filename, img, *args): diff --git a/mainscripts/Merger.py b/mainscripts/Merger.py index 4c9eb56..32d549a 100644 --- a/mainscripts/Merger.py +++ b/mainscripts/Merger.py @@ -232,6 +232,7 @@ class MergeSubprocessor(Subprocessor): except Exception as e: pass + rewind_to_frame_idx = None self.frames = frames self.frames_idxs = [ *range(len(self.frames)) ] self.frames_done_idxs = [] @@ -272,19 +273,15 @@ class MergeSubprocessor(Subprocessor): self.frames_idxs = s_frames_idxs self.frames_done_idxs = s_frames_done_idxs - 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 + rewind_to_frame_idx = -1 for frame in self.frames: frame.is_done = False - - 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) - + elif len(self.frames_idxs) == 0: + # all frames are done? + rewind_to_frame_idx = -1 + if len(self.frames_idxs) != 0: cur_frame = self.frames[self.frames_idxs[0]] cur_frame.is_shown = False @@ -307,7 +304,25 @@ class MergeSubprocessor(Subprocessor): frame.idx = i frame.output_filepath = self.output_path / ( frame.frame_info.filepath.stem + '.png' ) frame.output_mask_filepath = self.output_mask_path / ( frame.frame_info.filepath.stem + '.png' ) + + if not frame.output_filepath.exists() or \ + not frame.output_mask_filepath.exists(): + # if some frame does not exist, recompute and rewind + frame.is_done = False + frame.is_shown = False + + if rewind_to_frame_idx is None: + rewind_to_frame_idx = i-1 + else: + rewind_to_frame_idx = min(rewind_to_frame_idx, i-1) + if rewind_to_frame_idx is not None: + while len(self.frames_done_idxs) > 0: + if self.frames_done_idxs[-1] > rewind_to_frame_idx: + prev_frame = self.frames[self.frames_done_idxs.pop()] + self.frames_idxs.insert(0, prev_frame.idx) + else: + break #override def process_info_generator(self): r = [0] if MERGER_DEBUG else range(self.process_count) @@ -418,38 +433,37 @@ class MergeSubprocessor(Subprocessor): cur_frame = self.frames[self.frames_idxs[0]] if self.is_interactive: - self.main_screen.set_waiting_icon(False) + + screen_image = None if self.process_remain_frames else \ + self.main_screen.get_image() + + self.main_screen.set_image(None) + self.main_screen.set_waiting_icon( self.process_remain_frames or \ + self.is_interactive_quitting ) - if not self.is_interactive_quitting and not self.process_remain_frames: - if cur_frame is not None: - 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.filepath.name) ) + if cur_frame is not None and not self.is_interactive_quitting: + if not self.process_remain_frames: + if cur_frame.is_done: + if not cur_frame.is_shown: if cur_frame.image is None: - image = cv2_imread (cur_frame.output_filepath) - image_mask = cv2_imread (cur_frame.output_mask_filepath) + image = cv2_imread (cur_frame.output_filepath, verbose=False) + image_mask = cv2_imread (cur_frame.output_mask_filepath, verbose=False) if image is None or image_mask is None: # unable to read? recompute then cur_frame.is_done = False - cur_frame.is_shown = False else: image_mask = imagelib.normalize_channels(image_mask, 1) cur_frame.image = np.concatenate([image, image_mask], -1) - if cur_frame.is_done: - self.main_screen.set_image(cur_frame.image) - - else: - self.main_screen.set_waiting_icon(True) - - else: - self.main_screen.set_image(None) - else: - self.main_screen.set_image(None) - self.main_screen.set_waiting_icon(True) + if cur_frame.is_done: + io.log_info (cur_frame.cfg.to_string( cur_frame.frame_info.filepath.name) ) + cur_frame.is_shown = True + screen_image = cur_frame.image + else: + self.main_screen.set_waiting_icon(True) + self.main_screen.set_image(screen_image) self.screen_manager.show_current() key_events = self.screen_manager.get_key_events() diff --git a/mainscripts/MergerScreen/MergerScreen.py b/mainscripts/MergerScreen/MergerScreen.py index 6773cbd..fad2a8d 100644 --- a/mainscripts/MergerScreen/MergerScreen.py +++ b/mainscripts/MergerScreen/MergerScreen.py @@ -43,7 +43,10 @@ class Screen(object): def toggle_show_checker_board(self): self.show_checker_board = not self.show_checker_board self.force_update = True - + + def get_image(self): + return self.image + def set_image(self, img): if not img is self.image: self.force_update = True diff --git a/merger/MergeMasked.py b/merger/MergeMasked.py index c5ca2d8..1a74abc 100644 --- a/merger/MergeMasked.py +++ b/merger/MergeMasked.py @@ -100,7 +100,7 @@ def MergeMaskedFace (predictor_func, predictor_input_shape, cfg, frame_info, img elif cfg.mask_mode == 7: prd_face_mask_a_0 = prd_face_mask_a_0 * FAN_dst_face_mask_a_0 - prd_face_mask_a_0[ prd_face_mask_a_0 < 0.001 ] = 0.0 + prd_face_mask_a_0[ prd_face_mask_a_0 < (1.0/255.0) ] = 0.0 # get rid of noise # process mask in local predicted space @@ -123,7 +123,7 @@ def MergeMaskedFace (predictor_func, predictor_input_shape, cfg, frame_info, img # clip eroded/dilated mask in actual predict area # pad with half blur size in order to accuratelly fade to zero at the boundary clip_size = input_size + blur // 2 - + prd_face_mask_a_0[:clip_size,:] = 0 prd_face_mask_a_0[-clip_size:,:] = 0 prd_face_mask_a_0[:,:clip_size] = 0 @@ -132,14 +132,16 @@ def MergeMaskedFace (predictor_func, predictor_input_shape, cfg, frame_info, img if blur > 0: blur = blur + (1-blur % 2) prd_face_mask_a_0 = cv2.GaussianBlur(prd_face_mask_a_0, (blur, blur) , 0) - + prd_face_mask_a_0 = prd_face_mask_a_0[input_size:-input_size,input_size:-input_size] + prd_face_mask_a_0 = np.clip(prd_face_mask_a_0, 0, 1) img_face_mask_a = cv2.warpAffine( prd_face_mask_a_0, face_mask_output_mat, img_size, np.zeros(img_bgr.shape[0:2], dtype=np.float32), flags=cv2.WARP_INVERSE_MAP | cv2.INTER_CUBIC )[...,None] img_face_mask_a = np.clip (img_face_mask_a, 0.0, 1.0) - img_face_mask_a [ img_face_mask_a <= 0.1 ] = 0.0 #get rid of noise + img_face_mask_a [ img_face_mask_a < (1.0/255.0) ] = 0.0 # get rid of noise + if prd_face_mask_a_0.shape[0] != output_size: prd_face_mask_a_0 = cv2.resize (prd_face_mask_a_0, (output_size,output_size), cv2.INTER_CUBIC)