From 123bccf01a3246dbd04c3c7b1149e7369a2d0c9b Mon Sep 17 00:00:00 2001 From: Colombo Date: Sat, 7 Mar 2020 15:51:30 +0400 Subject: [PATCH] returned back 3.optional) denoise data_dst images.bat Apply it if dst video is very sharp. Denoise dst images before face extraction. This technique helps neural network not to learn the noise. The result is less pixel shake of the predicted face. --- main.py | 7 ++--- mainscripts/VideoEd.py | 66 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/main.py b/main.py index 660b03f..de6e0f8 100644 --- a/main.py +++ b/main.py @@ -258,10 +258,9 @@ if __name__ == "__main__": def process_videoed_denoise_image_sequence(arguments): osex.set_process_lowest_prio() from mainscripts import VideoEd - VideoEd.denoise_image_sequence (arguments.input_dir, arguments.ext, arguments.factor) - p = videoed_parser.add_parser( "denoise-image-sequence", help="Denoise sequence of images, keeping sharp edges. This allows you to make the final fake more believable, since the neural network is not able to make a detailed skin texture, but it makes the edges quite clear. Therefore, if the whole frame is more `blurred`, then a fake will seem more believable. Especially true for scenes of the film, which are usually very clear.") - p.add_argument('--input-dir', required=True, action=fixPathAction, dest="input_dir", help="Input file to be processed. Specify .*-extension to find first file.") - p.add_argument('--ext', dest="ext", default=None, help="Image format (extension) of input files.") + VideoEd.denoise_image_sequence (arguments.input_dir, arguments.factor) + p = videoed_parser.add_parser( "denoise-image-sequence", help="Denoise sequence of images, keeping sharp edges. Helps to remove pixel shake from the predicted face.") + p.add_argument('--input-dir', required=True, action=fixPathAction, dest="input_dir", help="Input directory to be processed.") p.add_argument('--factor', type=int, dest="factor", default=None, help="Denoise factor (1-20).") p.set_defaults(func=process_videoed_denoise_image_sequence) diff --git a/mainscripts/VideoEd.py b/mainscripts/VideoEd.py index 3d916f1..f9fcedd 100644 --- a/mainscripts/VideoEd.py +++ b/mainscripts/VideoEd.py @@ -92,20 +92,51 @@ def denoise_image_sequence( input_dir, ext=None, factor=None ): io.log_err("input_dir not found.") return - if ext is None: - ext = io.input_str ("Input image format (extension)", "png") + image_paths = [ Path(filepath) for filepath in pathex.get_image_paths(input_path) ] + + # Check extension of all images + image_paths_suffix = None + for filepath in image_paths: + if image_paths_suffix is None: + image_paths_suffix = filepath.suffix + else: + if filepath.suffix != image_paths_suffix: + io.log_err(f"All images in {input_path.name} should be with the same extension.") + return if factor is None: - factor = np.clip ( io.input_int ("Denoise factor?", 5, add_info="1-20"), 1, 20 ) + factor = np.clip ( io.input_int ("Denoise factor?", 7, add_info="1-20"), 1, 20 ) + # Rename to temporary filenames + for i,filepath in io.progress_bar_generator( enumerate(image_paths), "Renaming", leave=False): + src = filepath + dst = filepath.parent / ( f'{i+1:06}_{filepath.name}' ) + try: + src.rename (dst) + except: + io.log_error ('fail to rename %s' % (src.name) ) + return + + # Rename to sequental filenames + for i,filepath in io.progress_bar_generator( enumerate(image_paths), "Renaming", leave=False): + + src = filepath.parent / ( f'{i+1:06}_{filepath.name}' ) + dst = filepath.parent / ( f'{i+1:06}{filepath.suffix}' ) + try: + src.rename (dst) + except: + io.log_error ('fail to rename %s' % (src.name) ) + return + + # Process image sequence in ffmpeg kwargs = {} - if ext == 'jpg': + if image_paths_suffix == '.jpg': kwargs.update ({'q:v':'2'}) job = ( ffmpeg - .input(str ( input_path / ('%5d.'+ext) ) ) + .input(str ( input_path / ('%6d'+image_paths_suffix) ) ) .filter("hqdn3d", factor, factor, 5,5) - .output(str ( input_path / ('%5d.'+ext) ), **kwargs ) + .output(str ( input_path / ('%6d'+image_paths_suffix) ), **kwargs ) ) try: @@ -113,6 +144,27 @@ def denoise_image_sequence( input_dir, ext=None, factor=None ): except: io.log_err ("ffmpeg fail, job commandline:" + str(job.compile()) ) + # Rename to temporary filenames + for i,filepath in io.progress_bar_generator( enumerate(image_paths), "Renaming", leave=False): + src = filepath.parent / ( f'{i+1:06}{filepath.suffix}' ) + dst = filepath.parent / ( f'{i+1:06}_{filepath.name}' ) + try: + src.rename (dst) + except: + io.log_error ('fail to rename %s' % (src.name) ) + return + + # Rename to initial filenames + for i,filepath in io.progress_bar_generator( enumerate(image_paths), "Renaming", leave=False): + src = filepath.parent / ( f'{i+1:06}_{filepath.name}' ) + dst = filepath + + try: + src.rename (dst) + except: + io.log_error ('fail to rename %s' % (src.name) ) + return + def video_from_sequence( input_dir, output_file, reference_file=None, ext=None, fps=None, bitrate=None, include_audio=False, lossless=None ): input_path = Path(input_dir) output_file_path = Path(output_file) @@ -194,7 +246,7 @@ def video_from_sequence( input_dir, output_file, reference_file=None, ext=None, "b:v": "%dM" %(bitrate), "pix_fmt": "yuv420p", }) - + if include_audio and ref_in_a is not None: output_kwargs.update ({"c:a": "aac", "b:a": "192k",