diff --git a/README.md b/README.md index 66a1da2..7fc9594 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ You can now use the virtual camera output (uses pyvirtualcam) by turning on the Additional command line arguments are given below. To learn out what they do, check [this guide](https://github.com/s0md3v/roop/wiki/Advanced-Options). + ``` options: -h, --help show this help message and exit @@ -167,11 +168,17 @@ options: --headless run in headless mode --enhancer-upscale-factor Sets the upscale factor for the enhancer. Only applies if `face_enhancer` is set as a frame-processor --source-image-scaling-factor Set the upscale factor for source images. Only applies if `face_swapper` is set as a frame-processor + -r SCALE, --super-resolution-scale-factor SCALE Super resolution scale factor, choices are 2, 3, 4 -v, --version show program's version number and exit ``` Looking for a CLI mode? Using the -s/--source argument will make the run program in cli mode. +To improve the video quality, you can use the `super_resolution` frame processor after swapping the faces. It will enhance the video quality by 2x, 3x or 4x. You can set the upscale factor using the `-r` or `--super-resolution-scale-factor` argument. +Processing time will increase with the upscale factor, it's quite quick though. + +``` + ## Credits - [henryruhs](https://github.com/henryruhs): for being an irreplaceable contributor to the project - [ffmpeg](https://ffmpeg.org/): for making video related operations easy diff --git a/modules/core.py b/modules/core.py index 185e8f5..d248f97 100644 --- a/modules/core.py +++ b/modules/core.py @@ -51,14 +51,19 @@ def parse_args() -> None: program.add_argument('-t', '--target', help='Select a target image or video', dest='target_path') program.add_argument('-o', '--output', help='Select output file or directory', dest='output_path') program.add_argument('--frame-processor', help='Pipeline of frame processors', dest='frame_processor', - default=['face_swapper'], choices=['face_swapper', 'face_enhancer', 'super_resolution'], nargs='+') + default=['face_swapper'], choices=['face_swapper', 'face_enhancer', 'super_resolution'], + nargs='+') program.add_argument('--keep-fps', help='Keep original fps', dest='keep_fps', action='store_true', default=False) - program.add_argument('--keep-audio', help='Keep original audio', dest='keep_audio', action='store_true', default=True) - program.add_argument('--keep-frames', help='Keep temporary frames', dest='keep_frames', action='store_true', default=False) - program.add_argument('--many-faces', help='Process every face', dest='many_faces', action='store_true', default=False) + program.add_argument('--keep-audio', help='Keep original audio', dest='keep_audio', action='store_true', + default=True) + program.add_argument('--keep-frames', help='Keep temporary frames', dest='keep_frames', action='store_true', + default=False) + program.add_argument('--many-faces', help='Process every face', dest='many_faces', action='store_true', + default=False) program.add_argument('--video-encoder', help='Adjust output video encoder', dest='video_encoder', default='libx264', choices=['libx264', 'libx265', 'libvpx-vp9']) - program.add_argument('--video-quality', help='Adjust output video quality', dest='video_quality', type=int, default=18, + program.add_argument('--video-quality', help='Adjust output video quality', dest='video_quality', type=int, + default=18, choices=range(52), metavar='[0-51]') program.add_argument('--live-mirror', help='The live camera display as you see it in the front-facing camera frame', dest='live_mirror', action='store_true', default=False) @@ -76,6 +81,8 @@ def parse_args() -> None: dest='enhancer_upscale_factor', type=int, default=1) program.add_argument('--source-image-scaling-factor', help='Set the upscale factor for source images', dest='source_image_scaling_factor', default=2, type=int) + program.add_argument('-r', '--super-resolution-scale-factor', dest='super_resolution_scale_factor', + help='Set the upscale factor for super resolution', default=4, choices=[2, 3, 4], type=int) program.add_argument('-v', '--version', action='version', version=f'{modules.metadata.name} {modules.metadata.version}') @@ -107,6 +114,7 @@ def parse_args() -> None: modules.globals.headless = args.headless modules.globals.enhancer_upscale_factor = args.enhancer_upscale_factor modules.globals.source_image_scaling_factor = args.source_image_scaling_factor + modules.globals.sr_scale_factor = args.super_resolution_scale_factor # Handle face enhancer tumbler modules.globals.fp_ui['face_enhancer'] = 'face_enhancer' in args.frame_processor @@ -191,12 +199,14 @@ def limit_resources() -> None: try: soft, hard = resource.getrlimit(resource.RLIMIT_DATA) if memory > hard: - print(f"Warning: Requested memory limit {memory / (1024 ** 3)} GB exceeds system's hard limit. Setting to maximum allowed {hard / (1024 ** 3)} GB.") + print( + f"Warning: Requested memory limit {memory / (1024 ** 3)} GB exceeds system's hard limit. Setting to maximum allowed {hard / (1024 ** 3)} GB.") memory = hard resource.setrlimit(resource.RLIMIT_DATA, (memory, memory)) except ValueError as e: print(f"Warning: Could not set memory limit: {e}. Continuing with default limits.") + def release_resources() -> None: if 'cuda' in modules.globals.execution_providers: torch.cuda.empty_cache() @@ -250,7 +260,8 @@ def process_image_to_image() -> None: for frame_processor in get_frame_processors_modules(modules.globals.frame_processors): update_status('Processing...', frame_processor.NAME) - frame_processor.process_image(modules.globals.source_path, modules.globals.output_path, modules.globals.output_path) + frame_processor.process_image(modules.globals.source_path, modules.globals.output_path, + modules.globals.output_path) release_resources() if is_image(modules.globals.target_path): diff --git a/modules/globals.py b/modules/globals.py index 341246d..a6c63c3 100644 --- a/modules/globals.py +++ b/modules/globals.py @@ -31,4 +31,5 @@ nsfw = None camera_input_combobox = None webcam_preview_running = False enhancer_upscale_factor = 1 -source_image_scaling_factor = 2 \ No newline at end of file +source_image_scaling_factor = 2 +sr_scale_factor = 4 \ No newline at end of file diff --git a/modules/processors/frame/super_resolution.py b/modules/processors/frame/super_resolution.py index 374daed..13d9a5f 100644 --- a/modules/processors/frame/super_resolution.py +++ b/modules/processors/frame/super_resolution.py @@ -20,7 +20,7 @@ class SuperResolutionModel: _instance = None _lock = threading.Lock() - def __init__(self, sr_model_path: str = 'ESPCN_x4.pb'): + def __init__(self, sr_model_path: str = f'ESPCN_x{modules.globals.sr_scale_factor}.pb'): if SuperResolutionModel._instance is not None: raise Exception("This class is a singleton!") self.sr = cv2.dnn_superres.DnnSuperResImpl_create() @@ -29,21 +29,20 @@ class SuperResolutionModel: raise FileNotFoundError(f"Super-resolution model not found at {self.model_path}") try: self.sr.readModel(self.model_path) - self.sr.setModel("espcn", 4) # Using ESPCN with 4x upscaling + self.sr.setModel("espcn", modules.globals.sr_scale_factor) # Using ESPCN with 2,3 or 4x upscaling except Exception as e: print(f"Error during super-resolution model initialization: {e}") raise e @classmethod - def get_instance(cls, sr_model_path: str = 'ESPCN_x4.pb'): + def get_instance(cls, sr_model_path: str = f'ESPCN_x{modules.globals.sr_scale_factor}.pb'): if cls._instance is None: with cls._lock: if cls._instance is None: try: cls._instance = cls(sr_model_path) except Exception as e: - print(f"Failed to initialize SuperResolutionModel: {e}") - return None + raise RuntimeError(f"Failed to initialize SuperResolution: {str(e)}") return cls._instance @@ -54,7 +53,7 @@ def pre_check() -> bool: download_directory_path = resolve_relative_path('../models') # Download the super-resolution model as well conditional_download(download_directory_path, [ - 'https://huggingface.co/spaces/PabloGabrielSch/AI_Resolution_Upscaler_And_Resizer/resolve/bcd13b766a9499196e8becbe453c4a848673b3b6/models/ESPCN_x4.pb' + f'https://huggingface.co/spaces/PabloGabrielSch/AI_Resolution_Upscaler_And_Resizer/resolve/bcd13b766a9499196e8becbe453c4a848673b3b6/models/ESPCN_x{modules.globals.sr_scale_factor}.pb' ]) return True