mirror of
https://github.com/iperov/DeepFaceLab.git
synced 2025-07-07 05:22:06 -07:00
Merger: fixes and better quality
This commit is contained in:
parent
05f32d678d
commit
b24b1e2950
4 changed files with 57 additions and 37 deletions
|
@ -4,7 +4,7 @@ from pathlib import Path
|
||||||
from core.interact import interact as io
|
from core.interact import interact as io
|
||||||
import traceback
|
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
|
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)
|
numpyarray = np.asarray(bytes, dtype=np.uint8)
|
||||||
return cv2.imdecode(numpyarray, flags)
|
return cv2.imdecode(numpyarray, flags)
|
||||||
except:
|
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
|
return None
|
||||||
|
|
||||||
def cv2_imwrite(filename, img, *args):
|
def cv2_imwrite(filename, img, *args):
|
||||||
|
|
|
@ -232,6 +232,7 @@ class MergeSubprocessor(Subprocessor):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
rewind_to_frame_idx = None
|
||||||
self.frames = frames
|
self.frames = frames
|
||||||
self.frames_idxs = [ *range(len(self.frames)) ]
|
self.frames_idxs = [ *range(len(self.frames)) ]
|
||||||
self.frames_done_idxs = []
|
self.frames_done_idxs = []
|
||||||
|
@ -272,19 +273,15 @@ class MergeSubprocessor(Subprocessor):
|
||||||
self.frames_idxs = s_frames_idxs
|
self.frames_idxs = s_frames_idxs
|
||||||
self.frames_done_idxs = s_frames_done_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:
|
if self.model_iter != s_model_iter:
|
||||||
# model was more trained, recompute all frames
|
# model was more trained, recompute all frames
|
||||||
rewind_to_begin = True
|
rewind_to_frame_idx = -1
|
||||||
for frame in self.frames:
|
for frame in self.frames:
|
||||||
frame.is_done = False
|
frame.is_done = False
|
||||||
|
elif len(self.frames_idxs) == 0:
|
||||||
if rewind_to_begin:
|
# all frames are done?
|
||||||
while len(self.frames_done_idxs) > 0:
|
rewind_to_frame_idx = -1
|
||||||
prev_frame = self.frames[self.frames_done_idxs.pop()]
|
|
||||||
self.frames_idxs.insert(0, prev_frame.idx)
|
|
||||||
|
|
||||||
if len(self.frames_idxs) != 0:
|
if len(self.frames_idxs) != 0:
|
||||||
cur_frame = self.frames[self.frames_idxs[0]]
|
cur_frame = self.frames[self.frames_idxs[0]]
|
||||||
cur_frame.is_shown = False
|
cur_frame.is_shown = False
|
||||||
|
@ -307,7 +304,25 @@ class MergeSubprocessor(Subprocessor):
|
||||||
frame.idx = i
|
frame.idx = i
|
||||||
frame.output_filepath = self.output_path / ( frame.frame_info.filepath.stem + '.png' )
|
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' )
|
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
|
#override
|
||||||
def process_info_generator(self):
|
def process_info_generator(self):
|
||||||
r = [0] if MERGER_DEBUG else range(self.process_count)
|
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]]
|
cur_frame = self.frames[self.frames_idxs[0]]
|
||||||
|
|
||||||
if self.is_interactive:
|
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 and not self.is_interactive_quitting:
|
||||||
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 not self.process_remain_frames:
|
||||||
|
if cur_frame.is_done:
|
||||||
|
if not cur_frame.is_shown:
|
||||||
if cur_frame.image is None:
|
if cur_frame.image is None:
|
||||||
image = cv2_imread (cur_frame.output_filepath)
|
image = cv2_imread (cur_frame.output_filepath, verbose=False)
|
||||||
image_mask = cv2_imread (cur_frame.output_mask_filepath)
|
image_mask = cv2_imread (cur_frame.output_mask_filepath, verbose=False)
|
||||||
if image is None or image_mask is None:
|
if image is None or image_mask is None:
|
||||||
# unable to read? recompute then
|
# unable to read? recompute then
|
||||||
cur_frame.is_done = False
|
cur_frame.is_done = False
|
||||||
cur_frame.is_shown = False
|
|
||||||
else:
|
else:
|
||||||
image_mask = imagelib.normalize_channels(image_mask, 1)
|
image_mask = imagelib.normalize_channels(image_mask, 1)
|
||||||
cur_frame.image = np.concatenate([image, image_mask], -1)
|
cur_frame.image = np.concatenate([image, image_mask], -1)
|
||||||
|
|
||||||
if cur_frame.is_done:
|
if cur_frame.is_done:
|
||||||
self.main_screen.set_image(cur_frame.image)
|
io.log_info (cur_frame.cfg.to_string( cur_frame.frame_info.filepath.name) )
|
||||||
|
cur_frame.is_shown = True
|
||||||
else:
|
screen_image = cur_frame.image
|
||||||
self.main_screen.set_waiting_icon(True)
|
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)
|
|
||||||
|
|
||||||
|
self.main_screen.set_image(screen_image)
|
||||||
self.screen_manager.show_current()
|
self.screen_manager.show_current()
|
||||||
|
|
||||||
key_events = self.screen_manager.get_key_events()
|
key_events = self.screen_manager.get_key_events()
|
||||||
|
|
|
@ -43,7 +43,10 @@ class Screen(object):
|
||||||
def toggle_show_checker_board(self):
|
def toggle_show_checker_board(self):
|
||||||
self.show_checker_board = not self.show_checker_board
|
self.show_checker_board = not self.show_checker_board
|
||||||
self.force_update = True
|
self.force_update = True
|
||||||
|
|
||||||
|
def get_image(self):
|
||||||
|
return self.image
|
||||||
|
|
||||||
def set_image(self, img):
|
def set_image(self, img):
|
||||||
if not img is self.image:
|
if not img is self.image:
|
||||||
self.force_update = True
|
self.force_update = True
|
||||||
|
|
|
@ -100,7 +100,7 @@ def MergeMaskedFace (predictor_func, predictor_input_shape, cfg, frame_info, img
|
||||||
elif cfg.mask_mode == 7:
|
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 * 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
|
# 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
|
# clip eroded/dilated mask in actual predict area
|
||||||
# pad with half blur size in order to accuratelly fade to zero at the boundary
|
# pad with half blur size in order to accuratelly fade to zero at the boundary
|
||||||
clip_size = input_size + blur // 2
|
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
|
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:
|
if blur > 0:
|
||||||
blur = blur + (1-blur % 2)
|
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 = 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 = 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)
|
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 = 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 = 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:
|
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)
|
prd_face_mask_a_0 = cv2.resize (prd_face_mask_a_0, (output_size,output_size), cv2.INTER_CUBIC)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue