Significantly improve video resolution/quality using ESPCN_x4 model
parent
1af9abda2f
commit
2066560a95
|
@ -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).
|
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:
|
options:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
|
@ -167,11 +168,17 @@ options:
|
||||||
--headless run in headless mode
|
--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
|
--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
|
--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
|
-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.
|
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
|
## Credits
|
||||||
- [henryruhs](https://github.com/henryruhs): for being an irreplaceable contributor to the project
|
- [henryruhs](https://github.com/henryruhs): for being an irreplaceable contributor to the project
|
||||||
- [ffmpeg](https://ffmpeg.org/): for making video related operations easy
|
- [ffmpeg](https://ffmpeg.org/): for making video related operations easy
|
||||||
|
|
|
@ -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('-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('-o', '--output', help='Select output file or directory', dest='output_path')
|
||||||
program.add_argument('--frame-processor', help='Pipeline of frame processors', dest='frame_processor',
|
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-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-audio', help='Keep original audio', dest='keep_audio', action='store_true',
|
||||||
program.add_argument('--keep-frames', help='Keep temporary frames', dest='keep_frames', action='store_true', default=False)
|
default=True)
|
||||||
program.add_argument('--many-faces', help='Process every face', dest='many_faces', action='store_true', default=False)
|
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',
|
program.add_argument('--video-encoder', help='Adjust output video encoder', dest='video_encoder', default='libx264',
|
||||||
choices=['libx264', 'libx265', 'libvpx-vp9'])
|
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]')
|
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',
|
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)
|
dest='live_mirror', action='store_true', default=False)
|
||||||
|
@ -76,6 +81,8 @@ def parse_args() -> None:
|
||||||
dest='enhancer_upscale_factor', type=int, default=1)
|
dest='enhancer_upscale_factor', type=int, default=1)
|
||||||
program.add_argument('--source-image-scaling-factor', help='Set the upscale factor for source images',
|
program.add_argument('--source-image-scaling-factor', help='Set the upscale factor for source images',
|
||||||
dest='source_image_scaling_factor', default=2, type=int)
|
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',
|
program.add_argument('-v', '--version', action='version',
|
||||||
version=f'{modules.metadata.name} {modules.metadata.version}')
|
version=f'{modules.metadata.name} {modules.metadata.version}')
|
||||||
|
|
||||||
|
@ -107,6 +114,7 @@ def parse_args() -> None:
|
||||||
modules.globals.headless = args.headless
|
modules.globals.headless = args.headless
|
||||||
modules.globals.enhancer_upscale_factor = args.enhancer_upscale_factor
|
modules.globals.enhancer_upscale_factor = args.enhancer_upscale_factor
|
||||||
modules.globals.source_image_scaling_factor = args.source_image_scaling_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
|
# Handle face enhancer tumbler
|
||||||
modules.globals.fp_ui['face_enhancer'] = 'face_enhancer' in args.frame_processor
|
modules.globals.fp_ui['face_enhancer'] = 'face_enhancer' in args.frame_processor
|
||||||
|
|
||||||
|
@ -191,12 +199,14 @@ def limit_resources() -> None:
|
||||||
try:
|
try:
|
||||||
soft, hard = resource.getrlimit(resource.RLIMIT_DATA)
|
soft, hard = resource.getrlimit(resource.RLIMIT_DATA)
|
||||||
if memory > hard:
|
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
|
memory = hard
|
||||||
resource.setrlimit(resource.RLIMIT_DATA, (memory, memory))
|
resource.setrlimit(resource.RLIMIT_DATA, (memory, memory))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
print(f"Warning: Could not set memory limit: {e}. Continuing with default limits.")
|
print(f"Warning: Could not set memory limit: {e}. Continuing with default limits.")
|
||||||
|
|
||||||
|
|
||||||
def release_resources() -> None:
|
def release_resources() -> None:
|
||||||
if 'cuda' in modules.globals.execution_providers:
|
if 'cuda' in modules.globals.execution_providers:
|
||||||
torch.cuda.empty_cache()
|
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):
|
for frame_processor in get_frame_processors_modules(modules.globals.frame_processors):
|
||||||
update_status('Processing...', frame_processor.NAME)
|
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()
|
release_resources()
|
||||||
|
|
||||||
if is_image(modules.globals.target_path):
|
if is_image(modules.globals.target_path):
|
||||||
|
|
|
@ -31,4 +31,5 @@ nsfw = None
|
||||||
camera_input_combobox = None
|
camera_input_combobox = None
|
||||||
webcam_preview_running = False
|
webcam_preview_running = False
|
||||||
enhancer_upscale_factor = 1
|
enhancer_upscale_factor = 1
|
||||||
source_image_scaling_factor = 2
|
source_image_scaling_factor = 2
|
||||||
|
sr_scale_factor = 4
|
|
@ -20,7 +20,7 @@ class SuperResolutionModel:
|
||||||
_instance = None
|
_instance = None
|
||||||
_lock = threading.Lock()
|
_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:
|
if SuperResolutionModel._instance is not None:
|
||||||
raise Exception("This class is a singleton!")
|
raise Exception("This class is a singleton!")
|
||||||
self.sr = cv2.dnn_superres.DnnSuperResImpl_create()
|
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}")
|
raise FileNotFoundError(f"Super-resolution model not found at {self.model_path}")
|
||||||
try:
|
try:
|
||||||
self.sr.readModel(self.model_path)
|
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:
|
except Exception as e:
|
||||||
print(f"Error during super-resolution model initialization: {e}")
|
print(f"Error during super-resolution model initialization: {e}")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
@classmethod
|
@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:
|
if cls._instance is None:
|
||||||
with cls._lock:
|
with cls._lock:
|
||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
try:
|
try:
|
||||||
cls._instance = cls(sr_model_path)
|
cls._instance = cls(sr_model_path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to initialize SuperResolutionModel: {e}")
|
raise RuntimeError(f"Failed to initialize SuperResolution: {str(e)}")
|
||||||
return None
|
|
||||||
return cls._instance
|
return cls._instance
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +53,7 @@ def pre_check() -> bool:
|
||||||
download_directory_path = resolve_relative_path('../models')
|
download_directory_path = resolve_relative_path('../models')
|
||||||
# Download the super-resolution model as well
|
# Download the super-resolution model as well
|
||||||
conditional_download(download_directory_path, [
|
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
|
return True
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue