mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-25 00:52:18 +08:00
formatted code with black
This commit is contained in:
@@ -27,8 +27,7 @@ from avalon_framework import Avalon
|
||||
|
||||
|
||||
class WrapperMain:
|
||||
""" Anime4K CPP wrapper
|
||||
"""
|
||||
"""Anime4K CPP wrapper"""
|
||||
|
||||
def __init__(self, driver_settings):
|
||||
self.driver_settings = driver_settings
|
||||
@@ -38,53 +37,55 @@ class WrapperMain:
|
||||
def zero_to_one_float(value):
|
||||
value = float(value)
|
||||
if value < 0.0 or value > 1.0:
|
||||
raise argparse.ArgumentTypeError(f'{value} is not between 0.0 and 1.0')
|
||||
raise argparse.ArgumentTypeError(f"{value} is not between 0.0 and 1.0")
|
||||
return value
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('-i', '--input', type=str, help=argparse.SUPPRESS) # help='File for loading')
|
||||
parser.add_argument('-o', '--output', type=str, help=argparse.SUPPRESS) # help='File for outputting')
|
||||
parser.add_argument('-p', '--passes', type=int, help='Passes for processing')
|
||||
parser.add_argument('-n', '--pushColorCount', type=int, help='Limit the number of color pushes')
|
||||
parser.add_argument('-c', '--strengthColor', type=WrapperMain.zero_to_one_float, help='Strength for pushing color,range 0 to 1,higher for thinner')
|
||||
parser.add_argument('-g', '--strengthGradient', type=WrapperMain.zero_to_one_float, help='Strength for pushing gradient,range 0 to 1,higher for sharper')
|
||||
parser.add_argument('-z', '--zoomFactor', type=float, help='zoom factor for resizing')
|
||||
parser.add_argument('-t', '--threads', type=int, help='Threads count for video processing')
|
||||
parser.add_argument('-f', '--fastMode', action='store_true', help='Faster but maybe low quality')
|
||||
parser.add_argument('-v', '--videoMode', action='store_true', help='Video process')
|
||||
parser.add_argument('-s', '--preview', action='store_true', help='Preview image')
|
||||
parser.add_argument('-b', '--preprocessing', action='store_true', help='Enable pre processing')
|
||||
parser.add_argument('-a', '--postprocessing', action='store_true', help='Enable post processing')
|
||||
parser.add_argument('-r', '--preFilters', type=int, help='Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D)')
|
||||
parser.add_argument('-e', '--postFilters', type=int, help='Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P')
|
||||
parser.add_argument('-q', '--GPUMode', action='store_true', help='Enable GPU acceleration')
|
||||
parser.add_argument('-w', '--CNNMode', action='store_true', help='Enable ACNet')
|
||||
parser.add_argument('-H', '--HDN', action='store_true', help='Enable HDN mode for ACNet')
|
||||
parser.add_argument('-L', '--HDNLevel', type=int, help='Set HDN level')
|
||||
parser.add_argument('-l', '--listGPUs', action='store_true', help='list GPUs')
|
||||
parser.add_argument('-h', '--platformID', type=int, help='Specify the platform ID')
|
||||
parser.add_argument('-d', '--deviceID', type=int, help='Specify the device ID')
|
||||
parser.add_argument('-C', '--codec', type=str, help='Specify the codec for encoding from mp4v(recommended in Windows), dxva(for Windows), avc1(H264, recommended in Linux), vp09(very slow), hevc(not support in Windowds), av01(not support in Windowds) (string [=mp4v])')
|
||||
parser.add_argument('-F', '--forceFps', type=float, help='Set output video fps to the specifying number, 0 to disable')
|
||||
parser.add_argument('-D', '--disableProgress', action='store_true', help='disable progress display')
|
||||
parser.add_argument('-W', '--webVideo', type=str, help='process the video from URL')
|
||||
parser.add_argument('-A', '--alpha', action='store_true', help='preserve the Alpha channel for transparent image')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("-i", "--input", type=str, help=argparse.SUPPRESS) # help="File for loading")
|
||||
parser.add_argument("-o", "--output", type=str, help=argparse.SUPPRESS) # help="File for outputting")
|
||||
parser.add_argument("-p", "--passes", type=int, help="Passes for processing")
|
||||
parser.add_argument("-n", "--pushColorCount", type=int, help="Limit the number of color pushes")
|
||||
parser.add_argument("-c", "--strengthColor", type=WrapperMain.zero_to_one_float, help="Strength for pushing color,range 0 to 1,higher for thinner")
|
||||
parser.add_argument("-g", "--strengthGradient", type=WrapperMain.zero_to_one_float, help="Strength for pushing gradient,range 0 to 1,higher for sharper")
|
||||
parser.add_argument("-z", "--zoomFactor", type=float, help="zoom factor for resizing")
|
||||
parser.add_argument("-t", "--threads", type=int, help="Threads count for video processing")
|
||||
parser.add_argument("-f", "--fastMode", action="store_true", help="Faster but maybe low quality")
|
||||
parser.add_argument("-v", "--videoMode", action="store_true", help="Video process")
|
||||
parser.add_argument("-s", "--preview", action="store_true", help="Preview image")
|
||||
parser.add_argument("-b", "--preprocessing", action="store_true", help="Enable pre processing")
|
||||
parser.add_argument("-a", "--postprocessing", action="store_true", help="Enable post processing")
|
||||
parser.add_argument("-r", "--preFilters", type=int, help="Enhancement filter, only working when preProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D)")
|
||||
parser.add_argument("-e", "--postFilters", type=int, help="Enhancement filter, only working when postProcessing is true,there are 5 options by binary:Median blur=0000001, Mean blur=0000010, CAS Sharpening=0000100, Gaussian blur weak=0001000, Gaussian blur=0010000, Bilateral filter=0100000, Bilateral filter faster=1000000, you can freely combine them, eg: Gaussian blur weak + Bilateral filter = 0001000 | 0100000 = 0101000 = 40(D), so you can put 40 to enable Gaussian blur weak and Bilateral filter, which also is what I recommend for image that < 1080P, 48 for image that >= 1080P, and for performance I recommend to use 72 for video that < 1080P, 80 for video that >=1080P")
|
||||
parser.add_argument("-q", "--GPUMode", action="store_true", help="Enable GPU acceleration")
|
||||
parser.add_argument("-w", "--CNNMode", action="store_true", help="Enable ACNet")
|
||||
parser.add_argument("-H", "--HDN", action="store_true", help="Enable HDN mode for ACNet")
|
||||
parser.add_argument("-L", "--HDNLevel", type=int, help="Set HDN level")
|
||||
parser.add_argument("-l", "--listGPUs", action="store_true", help="list GPUs")
|
||||
parser.add_argument("-h", "--platformID", type=int, help="Specify the platform ID")
|
||||
parser.add_argument("-d", "--deviceID", type=int, help="Specify the device ID")
|
||||
parser.add_argument("-C", "--codec", type=str, help="Specify the codec for encoding from mp4v(recommended in Windows), dxva(for Windows), avc1(H264, recommended in Linux), vp09(very slow), hevc(not support in Windowds), av01(not support in Windowds) (string [=mp4v])")
|
||||
parser.add_argument("-F", "--forceFps", type=float, help="Set output video fps to the specifying number, 0 to disable")
|
||||
parser.add_argument("-D", "--disableProgress", action="store_true", help="disable progress display")
|
||||
parser.add_argument("-W", "--webVideo", type=str, help="process the video from URL")
|
||||
parser.add_argument("-A", "--alpha", action="store_true", help="preserve the Alpha channel for transparent image")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# self.driver_settings['zoomFactor'] = upscaler.scale_ratio
|
||||
self.driver_settings['threads'] = upscaler.processes
|
||||
self.driver_settings["threads"] = upscaler.processes
|
||||
|
||||
# append FFmpeg path to the end of PATH
|
||||
# Anime4KCPP will then use FFmpeg to migrate audio tracks
|
||||
os.environ['PATH'] += f';{upscaler.ffmpeg_settings["ffmpeg_path"]}'
|
||||
os.environ["PATH"] += f';{upscaler.ffmpeg_settings["ffmpeg_path"]}'
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: float):
|
||||
self.driver_settings['zoomFactor'] = scale_ratio
|
||||
self.driver_settings["zoomFactor"] = scale_ratio
|
||||
|
||||
def upscale(self, input_file, output_file):
|
||||
"""This is the core function for WAIFU2X class
|
||||
@@ -98,33 +99,33 @@ class WrapperMain:
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['input'] = input_file
|
||||
self.driver_settings['output'] = output_file
|
||||
self.driver_settings["input"] = input_file
|
||||
self.driver_settings["output"] = output_file
|
||||
|
||||
# Anime4KCPP will look for Anime4KCPPKernel.cl under the current working directory
|
||||
# change the CWD to its containing directory so it will find it
|
||||
if platform.system() == 'Windows':
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
if platform.system() == "Windows":
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with waifu2x binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -132,6 +133,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -27,20 +27,24 @@ class Ffmpeg:
|
||||
and inserting audio tracks to videos.
|
||||
"""
|
||||
|
||||
def __init__(self, ffmpeg_settings, extracted_frame_format='png'):
|
||||
def __init__(self, ffmpeg_settings, extracted_frame_format="png"):
|
||||
self.ffmpeg_settings = ffmpeg_settings
|
||||
|
||||
self.ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
||||
self.ffmpeg_binary = self.ffmpeg_path / 'ffmpeg'
|
||||
self.ffmpeg_probe_binary = self.ffmpeg_path / 'ffprobe'
|
||||
self.ffmpeg_path = pathlib.Path(self.ffmpeg_settings["ffmpeg_path"])
|
||||
self.ffmpeg_binary = self.ffmpeg_path / "ffmpeg"
|
||||
self.ffmpeg_probe_binary = self.ffmpeg_path / "ffprobe"
|
||||
|
||||
# video metadata
|
||||
self.extracted_frame_format = extracted_frame_format
|
||||
self.intermediate_file_name = pathlib.Path(self.ffmpeg_settings['intermediate_file_name'])
|
||||
self.pixel_format = self.ffmpeg_settings['extract_frames']['output_options']['-pix_fmt']
|
||||
self.intermediate_file_name = pathlib.Path(
|
||||
self.ffmpeg_settings["intermediate_file_name"]
|
||||
)
|
||||
self.pixel_format = self.ffmpeg_settings["extract_frames"]["output_options"][
|
||||
"-pix_fmt"
|
||||
]
|
||||
|
||||
def get_pixel_formats(self):
|
||||
""" Get a dictionary of supported pixel formats
|
||||
"""Get a dictionary of supported pixel formats
|
||||
|
||||
List all supported pixel formats and their
|
||||
corresponding bit depth.
|
||||
@@ -48,12 +52,7 @@ class Ffmpeg:
|
||||
Returns:
|
||||
dictionary -- JSON dict of all pixel formats to bit depth
|
||||
"""
|
||||
execute = [
|
||||
self.ffmpeg_probe_binary,
|
||||
'-v',
|
||||
'quiet',
|
||||
'-pix_fmts'
|
||||
]
|
||||
execute = [self.ffmpeg_probe_binary, "-v", "quiet", "-pix_fmts"]
|
||||
|
||||
# turn elements into str
|
||||
execute = [str(e) for e in execute]
|
||||
@@ -64,9 +63,15 @@ class Ffmpeg:
|
||||
pixel_formats = {}
|
||||
|
||||
# record all pixel formats into dictionary
|
||||
for line in subprocess.run(execute, check=True, stdout=subprocess.PIPE).stdout.decode().split('\n'):
|
||||
for line in (
|
||||
subprocess.run(execute, check=True, stdout=subprocess.PIPE)
|
||||
.stdout.decode()
|
||||
.split("\n")
|
||||
):
|
||||
try:
|
||||
pixel_formats[" ".join(line.split()).split()[1]] = int(" ".join(line.split()).split()[3])
|
||||
pixel_formats[" ".join(line.split()).split()[1]] = int(
|
||||
" ".join(line.split()).split()[3]
|
||||
)
|
||||
except (IndexError, ValueError):
|
||||
pass
|
||||
|
||||
@@ -76,7 +81,7 @@ class Ffmpeg:
|
||||
return pixel_formats
|
||||
|
||||
def get_number_of_frames(self, input_file: str, video_stream_index: int) -> int:
|
||||
""" Count the number of frames in a video
|
||||
"""Count the number of frames in a video
|
||||
|
||||
Args:
|
||||
input_file (str): input file path
|
||||
@@ -88,26 +93,30 @@ class Ffmpeg:
|
||||
|
||||
execute = [
|
||||
self.ffmpeg_probe_binary,
|
||||
'-v',
|
||||
'quiet',
|
||||
'-count_frames',
|
||||
'-select_streams',
|
||||
f'v:{video_stream_index}',
|
||||
'-show_entries',
|
||||
'stream=nb_read_frames',
|
||||
'-of',
|
||||
'default=nokey=1:noprint_wrappers=1',
|
||||
input_file
|
||||
"-v",
|
||||
"quiet",
|
||||
"-count_frames",
|
||||
"-select_streams",
|
||||
f"v:{video_stream_index}",
|
||||
"-show_entries",
|
||||
"stream=nb_read_frames",
|
||||
"-of",
|
||||
"default=nokey=1:noprint_wrappers=1",
|
||||
input_file,
|
||||
]
|
||||
|
||||
# turn elements into str
|
||||
execute = [str(e) for e in execute]
|
||||
|
||||
Avalon.debug_info(f'Executing: {" ".join(execute)}')
|
||||
return int(subprocess.run(execute, check=True, stdout=subprocess.PIPE).stdout.decode().strip())
|
||||
return int(
|
||||
subprocess.run(execute, check=True, stdout=subprocess.PIPE)
|
||||
.stdout.decode()
|
||||
.strip()
|
||||
)
|
||||
|
||||
def probe_file_info(self, input_video):
|
||||
""" Gets input video information
|
||||
"""Gets input video information
|
||||
|
||||
This method reads input video information
|
||||
using ffprobe in dictionary
|
||||
@@ -123,14 +132,14 @@ class Ffmpeg:
|
||||
# since video2x only strictly recignizes this one format
|
||||
execute = [
|
||||
self.ffmpeg_probe_binary,
|
||||
'-v',
|
||||
'quiet',
|
||||
'-print_format',
|
||||
'json',
|
||||
'-show_format',
|
||||
'-show_streams',
|
||||
'-i',
|
||||
input_video
|
||||
"-v",
|
||||
"quiet",
|
||||
"-print_format",
|
||||
"json",
|
||||
"-show_format",
|
||||
"-show_streams",
|
||||
"-i",
|
||||
input_video,
|
||||
]
|
||||
|
||||
# turn elements into str
|
||||
@@ -138,37 +147,38 @@ class Ffmpeg:
|
||||
|
||||
Avalon.debug_info(f'Executing: {" ".join(execute)}')
|
||||
json_str = subprocess.run(execute, check=True, stdout=subprocess.PIPE).stdout
|
||||
return json.loads(json_str.decode('utf-8'))
|
||||
return json.loads(json_str.decode("utf-8"))
|
||||
|
||||
def extract_frames(self, input_file, extracted_frames):
|
||||
""" extract frames from video or GIF file
|
||||
"""
|
||||
execute = [
|
||||
self.ffmpeg_binary
|
||||
]
|
||||
"""extract frames from video or GIF file"""
|
||||
execute = [self.ffmpeg_binary]
|
||||
|
||||
# load general options
|
||||
execute.extend(self._read_configuration(phase='extract_frames'))
|
||||
execute.extend(self._read_configuration(phase="extract_frames"))
|
||||
|
||||
# load input_options
|
||||
execute.extend(self._read_configuration(phase='extract_frames', section='input_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="extract_frames", section="input_options")
|
||||
)
|
||||
|
||||
# specify input file
|
||||
execute.extend([
|
||||
'-i',
|
||||
input_file
|
||||
])
|
||||
execute.extend(["-i", input_file])
|
||||
|
||||
# load output options
|
||||
execute.extend(self._read_configuration(phase='extract_frames', section='output_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="extract_frames", section="output_options")
|
||||
)
|
||||
|
||||
# specify output file
|
||||
execute.extend([
|
||||
extracted_frames / f'extracted_%0d.{self.extracted_frame_format}'
|
||||
# extracted_frames / f'frame_%06d.{self.extracted_frame_format}'
|
||||
])
|
||||
execute.extend(
|
||||
[
|
||||
extracted_frames
|
||||
/ f"extracted_%0d.{self.extracted_frame_format}"
|
||||
# extracted_frames / f'frame_%06d.{self.extracted_frame_format}'
|
||||
]
|
||||
)
|
||||
|
||||
return(self._execute(execute))
|
||||
return self._execute(execute)
|
||||
|
||||
def assemble_video(self, framerate, upscaled_frames):
|
||||
"""Converts images into videos
|
||||
@@ -182,86 +192,93 @@ class Ffmpeg:
|
||||
"""
|
||||
execute = [
|
||||
self.ffmpeg_binary,
|
||||
'-r',
|
||||
"-r",
|
||||
str(framerate)
|
||||
# '-s',
|
||||
# resolution
|
||||
]
|
||||
|
||||
# read other options
|
||||
execute.extend(self._read_configuration(phase='assemble_video'))
|
||||
execute.extend(self._read_configuration(phase="assemble_video"))
|
||||
|
||||
# read input options
|
||||
execute.extend(self._read_configuration(phase='assemble_video', section='input_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="assemble_video", section="input_options")
|
||||
)
|
||||
|
||||
# WORKAROUND FOR WAIFU2X-NCNN-VULKAN
|
||||
# Dev: SAT3LL
|
||||
# rename all .png.png suffixes to .png
|
||||
import re
|
||||
regex = re.compile(r'\.png\.png$', re.IGNORECASE)
|
||||
|
||||
regex = re.compile(r"\.png\.png$", re.IGNORECASE)
|
||||
for frame_name in upscaled_frames.iterdir():
|
||||
(upscaled_frames / frame_name).rename(upscaled_frames / regex.sub('.png', str(frame_name)))
|
||||
(upscaled_frames / frame_name).rename(
|
||||
upscaled_frames / regex.sub(".png", str(frame_name))
|
||||
)
|
||||
# END WORKAROUND
|
||||
|
||||
# append input frames path into command
|
||||
execute.extend([
|
||||
'-i',
|
||||
upscaled_frames / f'extracted_%d.{self.extracted_frame_format}'
|
||||
# upscaled_frames / f'%06d.{self.extracted_frame_format}'
|
||||
])
|
||||
execute.extend(
|
||||
[
|
||||
"-i",
|
||||
upscaled_frames / f"extracted_%d.{self.extracted_frame_format}"
|
||||
# upscaled_frames / f'%06d.{self.extracted_frame_format}'
|
||||
]
|
||||
)
|
||||
|
||||
# read FFmpeg output options
|
||||
execute.extend(self._read_configuration(phase='assemble_video', section='output_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="assemble_video", section="output_options")
|
||||
)
|
||||
|
||||
# specify output file location
|
||||
execute.extend([
|
||||
upscaled_frames / self.intermediate_file_name
|
||||
])
|
||||
execute.extend([upscaled_frames / self.intermediate_file_name])
|
||||
|
||||
return(self._execute(execute))
|
||||
return self._execute(execute)
|
||||
|
||||
def migrate_streams(self, input_video, output_video, upscaled_frames):
|
||||
""" Migrates audio tracks and subtitles from input video to output video
|
||||
"""Migrates audio tracks and subtitles from input video to output video
|
||||
|
||||
Arguments:
|
||||
input_video {string} -- input video file path
|
||||
output_video {string} -- output video file path
|
||||
upscaled_frames {string} -- directory containing upscaled frames
|
||||
"""
|
||||
execute = [
|
||||
self.ffmpeg_binary
|
||||
]
|
||||
execute = [self.ffmpeg_binary]
|
||||
|
||||
# load general options
|
||||
execute.extend(self._read_configuration(phase='migrate_streams'))
|
||||
execute.extend(self._read_configuration(phase="migrate_streams"))
|
||||
|
||||
# load input options
|
||||
execute.extend(self._read_configuration(phase='migrate_streams', section='input_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="migrate_streams", section="input_options")
|
||||
)
|
||||
|
||||
# load input file names
|
||||
execute.extend([
|
||||
|
||||
# input 1: upscaled intermediate file without sound
|
||||
'-i',
|
||||
upscaled_frames / self.intermediate_file_name,
|
||||
|
||||
# input 2: original video with streams to copy over
|
||||
'-i',
|
||||
input_video
|
||||
])
|
||||
execute.extend(
|
||||
[
|
||||
# input 1: upscaled intermediate file without sound
|
||||
"-i",
|
||||
upscaled_frames / self.intermediate_file_name,
|
||||
# input 2: original video with streams to copy over
|
||||
"-i",
|
||||
input_video,
|
||||
]
|
||||
)
|
||||
|
||||
# load output options
|
||||
execute.extend(self._read_configuration(phase='migrate_streams', section='output_options'))
|
||||
execute.extend(
|
||||
self._read_configuration(phase="migrate_streams", section="output_options")
|
||||
)
|
||||
|
||||
# load output video path
|
||||
execute.extend([
|
||||
output_video
|
||||
])
|
||||
execute.extend([output_video])
|
||||
|
||||
return(self._execute(execute))
|
||||
return self._execute(execute)
|
||||
|
||||
def _read_configuration(self, phase, section=None):
|
||||
""" read configuration from JSON
|
||||
"""read configuration from JSON
|
||||
|
||||
Read the configurations (arguments) from the JSON
|
||||
configuration file and append them to the end of the
|
||||
@@ -290,7 +307,12 @@ class Ffmpeg:
|
||||
value = self.ffmpeg_settings[phase][key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if value is None or value is False or isinstance(value, dict) or value == '':
|
||||
if (
|
||||
value is None
|
||||
or value is False
|
||||
or isinstance(value, dict)
|
||||
or value == ""
|
||||
):
|
||||
continue
|
||||
|
||||
# if the value is a list, append the same argument and all values
|
||||
|
||||
@@ -19,30 +19,37 @@ from avalon_framework import Avalon
|
||||
|
||||
|
||||
class Gifski:
|
||||
|
||||
def __init__(self, gifski_settings):
|
||||
self.gifski_settings = gifski_settings
|
||||
|
||||
def make_gif(self, upscaled_frames: pathlib.Path, output_path: pathlib.Path, framerate: float, extracted_frame_format: str, output_width: int, output_height: int) -> subprocess.Popen:
|
||||
def make_gif(
|
||||
self,
|
||||
upscaled_frames: pathlib.Path,
|
||||
output_path: pathlib.Path,
|
||||
framerate: float,
|
||||
extracted_frame_format: str,
|
||||
output_width: int,
|
||||
output_height: int,
|
||||
) -> subprocess.Popen:
|
||||
execute = [
|
||||
self.gifski_settings['gifski_path'],
|
||||
'-o',
|
||||
self.gifski_settings["gifski_path"],
|
||||
"-o",
|
||||
output_path,
|
||||
'--fps',
|
||||
"--fps",
|
||||
int(round(framerate, 0)),
|
||||
'--width',
|
||||
"--width",
|
||||
output_width,
|
||||
'--height',
|
||||
output_height
|
||||
"--height",
|
||||
output_height,
|
||||
]
|
||||
|
||||
# load configurations from config file
|
||||
execute.extend(self._load_configuration())
|
||||
|
||||
# append frames location
|
||||
execute.extend([upscaled_frames / f'extracted_*.{extracted_frame_format}'])
|
||||
execute.extend([upscaled_frames / f"extracted_*.{extracted_frame_format}"])
|
||||
|
||||
return(self._execute(execute))
|
||||
return self._execute(execute)
|
||||
|
||||
def _load_configuration(self):
|
||||
|
||||
@@ -53,13 +60,13 @@ class Gifski:
|
||||
value = self.gifski_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'gifski_path' or value is None or value is False:
|
||||
if key == "gifski_path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
configuration.append(f'-{key}')
|
||||
configuration.append(f"-{key}")
|
||||
else:
|
||||
configuration.append(f'--{key}')
|
||||
configuration.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -70,6 +77,6 @@ class Gifski:
|
||||
# turn all list elements into string to avoid errors
|
||||
execute = [str(e) for e in execute]
|
||||
|
||||
Avalon.debug_info(f'Executing: {execute}')
|
||||
Avalon.debug_info(f"Executing: {execute}")
|
||||
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -38,28 +38,32 @@ class WrapperMain:
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('-v', action='store_true', help='verbose output')
|
||||
parser.add_argument('-i', type=str, help=argparse.SUPPRESS) # help='input image path (jpg/png) or directory')
|
||||
parser.add_argument('-o', type=str, help=argparse.SUPPRESS) # help='output image path (png) or directory')
|
||||
parser.add_argument('-s', type=int, help='upscale ratio')
|
||||
parser.add_argument('-t', type=int, help='tile size (>=32/0=auto)')
|
||||
parser.add_argument('-m', type=str, help='realsr model path')
|
||||
parser.add_argument('-g', type=int, help='gpu device to use')
|
||||
parser.add_argument('-j', type=str, help='thread count for load/proc/save')
|
||||
parser.add_argument('-x', action='store_true', help='enable tta mode')
|
||||
parser.add_argument('-f', type=str, help=argparse.SUPPRESS) # help='output image format (jpg/png/webp, default=ext/png)')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("-v", action="store_true", help="verbose output")
|
||||
parser.add_argument("-i", type=str, help=argparse.SUPPRESS) # help="input image path (jpg/png) or directory")
|
||||
parser.add_argument("-o", type=str, help=argparse.SUPPRESS) # help="output image path (png) or directory")
|
||||
parser.add_argument("-s", type=int, help="upscale ratio")
|
||||
parser.add_argument("-t", type=int, help="tile size (>=32/0=auto)")
|
||||
parser.add_argument("-m", type=str, help="realsr model path")
|
||||
parser.add_argument("-g", type=int, help="gpu device to use")
|
||||
parser.add_argument("-j", type=str, help="thread count for load/proc/save")
|
||||
parser.add_argument("-x", action="store_true", help="enable tta mode")
|
||||
parser.add_argument("-f", type=str, help=argparse.SUPPRESS) # help="output image format (jpg/png/webp, default=ext/png)")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# self.driver_settings['s'] = int(upscaler.scale_ratio)
|
||||
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
|
||||
self.driver_settings['f'] = upscaler.extracted_frame_format.lower()
|
||||
self.driver_settings["j"] = "{}:{}:{}".format(
|
||||
upscaler.processes, upscaler.processes, upscaler.processes
|
||||
)
|
||||
self.driver_settings["f"] = upscaler.extracted_frame_format.lower()
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: int):
|
||||
self.driver_settings['s'] = int(scale_ratio)
|
||||
self.driver_settings["s"] = int(scale_ratio)
|
||||
|
||||
def upscale(self, input_directory, output_directory):
|
||||
"""This is the core function for RealSR NCNN Vulkan class
|
||||
@@ -72,33 +76,33 @@ class WrapperMain:
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['i'] = input_directory
|
||||
self.driver_settings['o'] = output_directory
|
||||
self.driver_settings["i"] = input_directory
|
||||
self.driver_settings["o"] = output_directory
|
||||
|
||||
# by default, realsr-ncnn-vulkan will look for the models under the current working directory
|
||||
# change the working directory to its containing folder if model directory not specified
|
||||
if self.driver_settings['m'] is None and platform.system() == 'Windows':
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
if self.driver_settings["m"] is None and platform.system() == "Windows":
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with the binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -106,6 +110,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -38,29 +38,33 @@ class WrapperMain:
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('-v', action='store_true', help='verbose output')
|
||||
parser.add_argument('-i', type=str, help=argparse.SUPPRESS) # help='input image path (jpg/png) or directory')
|
||||
parser.add_argument('-o', type=str, help=argparse.SUPPRESS) # help='output image path (png) or directory')
|
||||
parser.add_argument('-n', type=int, choices=range(-1, 11), help='denoise level')
|
||||
parser.add_argument('-s', type=int, help='upscale ratio')
|
||||
parser.add_argument('-t', type=int, help='tile size (>=32)')
|
||||
parser.add_argument('-m', type=str, help='srmd model path')
|
||||
parser.add_argument('-g', type=int, help='gpu device to use')
|
||||
parser.add_argument('-j', type=str, help='thread count for load/proc/save')
|
||||
parser.add_argument('-x', action='store_true', help='enable tta mode')
|
||||
parser.add_argument('-f', type=str, help=argparse.SUPPRESS) # help='output image format (jpg/png/webp, default=ext/png)')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("-v", action="store_true", help="verbose output")
|
||||
parser.add_argument("-i", type=str, help=argparse.SUPPRESS) # help="input image path (jpg/png) or directory")
|
||||
parser.add_argument("-o", type=str, help=argparse.SUPPRESS) # help="output image path (png) or directory")
|
||||
parser.add_argument("-n", type=int, choices=range(-1, 11), help="denoise level")
|
||||
parser.add_argument("-s", type=int, help="upscale ratio")
|
||||
parser.add_argument("-t", type=int, help="tile size (>=32)")
|
||||
parser.add_argument("-m", type=str, help="srmd model path")
|
||||
parser.add_argument("-g", type=int, help="gpu device to use")
|
||||
parser.add_argument("-j", type=str, help="thread count for load/proc/save")
|
||||
parser.add_argument("-x", action="store_true", help="enable tta mode")
|
||||
parser.add_argument("-f", type=str, help=argparse.SUPPRESS) # help="output image format (jpg/png/webp, default=ext/png)")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# self.driver_settings['s'] = int(upscaler.scale_ratio)
|
||||
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
|
||||
self.driver_settings['f'] = upscaler.extracted_frame_format.lower()
|
||||
self.driver_settings["j"] = "{}:{}:{}".format(
|
||||
upscaler.processes, upscaler.processes, upscaler.processes
|
||||
)
|
||||
self.driver_settings["f"] = upscaler.extracted_frame_format.lower()
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: int):
|
||||
self.driver_settings['s'] = int(scale_ratio)
|
||||
self.driver_settings["s"] = int(scale_ratio)
|
||||
|
||||
def upscale(self, input_directory, output_directory):
|
||||
"""This is the core function for SRMD ncnn Vulkan class
|
||||
@@ -73,33 +77,33 @@ class WrapperMain:
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['i'] = input_directory
|
||||
self.driver_settings['o'] = output_directory
|
||||
self.driver_settings["i"] = input_directory
|
||||
self.driver_settings["o"] = output_directory
|
||||
|
||||
# by default, srmd-ncnn-vulkan will look for the models under the current working directory
|
||||
# change the working directory to its containing folder if model directory not specified
|
||||
if self.driver_settings['m'] is None and platform.system() == 'Windows':
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
if self.driver_settings["m"] is None and platform.system() == "Windows":
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with the binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -107,6 +111,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -37,77 +37,78 @@ class WrapperMain:
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('-t', '--tta', type=int, choices=range(2), help='8x slower and slightly high quality')
|
||||
parser.add_argument('--gpu', type=int, help='gpu device no')
|
||||
parser.add_argument('-b', '--batch_size', type=int, help='input batch size')
|
||||
parser.add_argument('--crop_h', type=int, help='input image split size(height)')
|
||||
parser.add_argument('--crop_w', type=int, help='input image split size(width)')
|
||||
parser.add_argument('-c', '--crop_size', type=int, help='input image split size')
|
||||
parser.add_argument('-d', '--output_depth', type=int, help='output image chaneel depth bit')
|
||||
parser.add_argument('-q', '--output_quality', type=int, help='output image quality')
|
||||
parser.add_argument('-p', '--process', choices=['cpu', 'gpu', 'cudnn'], help='process mode')
|
||||
parser.add_argument('--model_dir', type=str, help='path to custom model directory (don\'t append last / )')
|
||||
parser.add_argument('-h', '--scale_height', type=int, help='custom scale height')
|
||||
parser.add_argument('-w', '--scale_width', type=int, help='custom scale width')
|
||||
parser.add_argument('-s', '--scale_ratio', type=float, help='custom scale ratio')
|
||||
parser.add_argument('-n', '--noise_level', type=int, choices=range(4), help='noise reduction level')
|
||||
parser.add_argument('-m', '--mode', choices=['noise', 'scale', 'noise_scale', 'auto_scale'], help='image processing mode')
|
||||
parser.add_argument('-e', '--output_extention', type=str, help='extention to output image file when output_path is (auto) or input_path is folder')
|
||||
parser.add_argument('-l', '--input_extention_list', type=str, help='extention to input image file when input_path is folder')
|
||||
parser.add_argument('-o', '--output_path', type=str, help=argparse.SUPPRESS) # help='path to output image file (when input_path is folder, output_path must be folder)')
|
||||
parser.add_argument('-i', '--input_path', type=str, help=argparse.SUPPRESS) # help='(required) path to input image file')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("-t", "--tta", type=int, choices=range(2), help="8x slower and slightly high quality")
|
||||
parser.add_argument("--gpu", type=int, help="gpu device no")
|
||||
parser.add_argument("-b", "--batch_size", type=int, help="input batch size")
|
||||
parser.add_argument("--crop_h", type=int, help="input image split size(height)")
|
||||
parser.add_argument("--crop_w", type=int, help="input image split size(width)")
|
||||
parser.add_argument("-c", "--crop_size", type=int, help="input image split size")
|
||||
parser.add_argument("-d", "--output_depth", type=int, help="output image chaneel depth bit")
|
||||
parser.add_argument("-q", "--output_quality", type=int, help="output image quality")
|
||||
parser.add_argument("-p", "--process", choices=["cpu", "gpu", "cudnn"], help="process mode")
|
||||
parser.add_argument("--model_dir", type=str, help="path to custom model directory (don\"t append last / )")
|
||||
parser.add_argument("-h", "--scale_height", type=int, help="custom scale height")
|
||||
parser.add_argument("-w", "--scale_width", type=int, help="custom scale width")
|
||||
parser.add_argument("-s", "--scale_ratio", type=float, help="custom scale ratio")
|
||||
parser.add_argument("-n", "--noise_level", type=int, choices=range(4), help="noise reduction level")
|
||||
parser.add_argument("-m", "--mode", choices=["noise", "scale", "noise_scale", "auto_scale"], help="image processing mode")
|
||||
parser.add_argument("-e", "--output_extention", type=str, help="extention to output image file when output_path is (auto) or input_path is folder")
|
||||
parser.add_argument("-l", "--input_extention_list", type=str, help="extention to input image file when input_path is folder")
|
||||
parser.add_argument("-o", "--output_path", type=str, help=argparse.SUPPRESS) # help="path to output image file (when input_path is folder, output_path must be folder)")
|
||||
parser.add_argument("-i", "--input_path", type=str, help=argparse.SUPPRESS) # help="(required) path to input image file")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# use scale width and scale height if specified
|
||||
# self.driver_settings['scale_ratio'] = upscaler.scale_ratio
|
||||
self.driver_settings['output_extention'] = upscaler.extracted_frame_format
|
||||
self.driver_settings["output_extention"] = upscaler.extracted_frame_format
|
||||
|
||||
# bit_depth will be 12 at this point
|
||||
# it will up updated later
|
||||
self.driver_settings['output_depth'] = 12
|
||||
self.driver_settings["output_depth"] = 12
|
||||
|
||||
def set_scale_resolution(self, width: int, height: int):
|
||||
self.driver_settings['scale_width'] = width
|
||||
self.driver_settings['scale_height'] = height
|
||||
self.driver_settings['scale_ratio'] = None
|
||||
self.driver_settings["scale_width"] = width
|
||||
self.driver_settings["scale_height"] = height
|
||||
self.driver_settings["scale_ratio"] = None
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: float):
|
||||
self.driver_settings['scale_width'] = None
|
||||
self.driver_settings['scale_height'] = None
|
||||
self.driver_settings['scale_ratio'] = scale_ratio
|
||||
self.driver_settings["scale_width"] = None
|
||||
self.driver_settings["scale_height"] = None
|
||||
self.driver_settings["scale_ratio"] = scale_ratio
|
||||
|
||||
def upscale(self, input_directory, output_directory):
|
||||
""" start upscaling process
|
||||
"""
|
||||
"""start upscaling process"""
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['input_path'] = input_directory
|
||||
self.driver_settings['output_path'] = output_directory
|
||||
self.driver_settings["input_path"] = input_directory
|
||||
self.driver_settings["output_path"] = output_directory
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with waifu2x binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -115,6 +116,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -37,45 +37,47 @@ class WrapperMain:
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('--list-supported-formats', action='store_true', help='dump currently supported format list')
|
||||
parser.add_argument('--list-opencv-formats', action='store_true', help='(deprecated. Use --list-supported-formats) dump opencv supported format list')
|
||||
parser.add_argument('-l', '--list-processor', action='store_true', help='dump processor list')
|
||||
parser.add_argument('-f', '--output-format', choices=['png', 'jpg'], help='The format used when running in recursive/folder mode\nSee --list-supported-formats for a list of supported formats/extensions.')
|
||||
parser.add_argument('-c', '--png-compression', type=int, choices=range(10), help='Set PNG compression level (0-9), 9 = Max compression (slowest & smallest)')
|
||||
parser.add_argument('-q', '--image-quality', type=int, choices=range(-1, 102), help='JPEG & WebP Compression quality (0-101, 0 being smallest size and lowest quality), use 101 for lossless WebP')
|
||||
parser.add_argument('--block-size', type=int, help='block size')
|
||||
parser.add_argument('--disable-gpu', action='store_true', help='disable GPU')
|
||||
parser.add_argument('--force-OpenCL', action='store_true', help='force to use OpenCL on Intel Platform')
|
||||
parser.add_argument('-p', '--processor', type=int, help='set target processor')
|
||||
parser.add_argument('-j', '--jobs', type=int, help='number of threads launching at the same time')
|
||||
parser.add_argument('--model-dir', type=str, help='path to custom model directory (don\'t append last / )')
|
||||
parser.add_argument('--scale-ratio', type=float, help='custom scale ratio')
|
||||
parser.add_argument('--noise-level', type=int, choices=range(4), help='noise reduction level')
|
||||
parser.add_argument('-m', '--mode', choices=['noise', 'scale', 'noise-scale'], help='image processing mode')
|
||||
parser.add_argument('-v', '--log-level', type=int, choices=range(5), help='Set log level')
|
||||
parser.add_argument('-s', '--silent', action='store_true', help='Enable silent mode. (same as --log-level 1)')
|
||||
parser.add_argument('-t', '--tta', type=int, choices=range(2), help='Enable Test-Time Augmentation mode.')
|
||||
parser.add_argument('-g', '--generate-subdir', type=int, choices=range(2), help='Generate sub folder when recursive directory is enabled.')
|
||||
parser.add_argument('-a', '--auto-naming', type=int, choices=range(2), help='Add postfix to output name when output path is not specified.\nSet 0 to disable this.')
|
||||
parser.add_argument('-r', '--recursive-directory', type=int, choices=range(2), help='Search recursively through directories to find more images to process.')
|
||||
parser.add_argument('-o', '--output', type=str, help=argparse.SUPPRESS) # help='path to output image file or directory (you should use the full path)')
|
||||
parser.add_argument('-i', '--input', type=str, help=argparse.SUPPRESS) # help='(required) path to input image file or directory (you should use the full path)')
|
||||
parser.add_argument('--version', action='store_true', help='Displays version information and exits.')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("--list-supported-formats", action="store_true", help="dump currently supported format list")
|
||||
parser.add_argument("--list-opencv-formats", action="store_true", help="(deprecated. Use --list-supported-formats) dump opencv supported format list")
|
||||
parser.add_argument("-l", "--list-processor", action="store_true", help="dump processor list")
|
||||
parser.add_argument("-f", "--output-format", choices=["png", "jpg"], help="The format used when running in recursive/folder mode\nSee --list-supported-formats for a list of supported formats/extensions.")
|
||||
parser.add_argument("-c", "--png-compression", type=int, choices=range(10), help="Set PNG compression level (0-9), 9 = Max compression (slowest & smallest)")
|
||||
parser.add_argument("-q", "--image-quality", type=int, choices=range(-1, 102), help="JPEG & WebP Compression quality (0-101, 0 being smallest size and lowest quality), use 101 for lossless WebP")
|
||||
parser.add_argument("--block-size", type=int, help="block size")
|
||||
parser.add_argument("--disable-gpu", action="store_true", help="disable GPU")
|
||||
parser.add_argument("--force-OpenCL", action="store_true", help="force to use OpenCL on Intel Platform")
|
||||
parser.add_argument("-p", "--processor", type=int, help="set target processor")
|
||||
parser.add_argument("-j", "--jobs", type=int, help="number of threads launching at the same time")
|
||||
parser.add_argument("--model-dir", type=str, help="path to custom model directory (don\"t append last / )")
|
||||
parser.add_argument("--scale-ratio", type=float, help="custom scale ratio")
|
||||
parser.add_argument("--noise-level", type=int, choices=range(4), help="noise reduction level")
|
||||
parser.add_argument("-m", "--mode", choices=["noise", "scale", "noise-scale"], help="image processing mode")
|
||||
parser.add_argument("-v", "--log-level", type=int, choices=range(5), help="Set log level")
|
||||
parser.add_argument("-s", "--silent", action="store_true", help="Enable silent mode. (same as --log-level 1)")
|
||||
parser.add_argument("-t", "--tta", type=int, choices=range(2), help="Enable Test-Time Augmentation mode.")
|
||||
parser.add_argument("-g", "--generate-subdir", type=int, choices=range(2), help="Generate sub folder when recursive directory is enabled.")
|
||||
parser.add_argument("-a", "--auto-naming", type=int, choices=range(2), help="Add postfix to output name when output path is not specified.\nSet 0 to disable this.")
|
||||
parser.add_argument("-r", "--recursive-directory", type=int, choices=range(2), help="Search recursively through directories to find more images to process.")
|
||||
parser.add_argument("-o", "--output", type=str, help=argparse.SUPPRESS) # help="path to output image file or directory (you should use the full path)")
|
||||
parser.add_argument("-i", "--input", type=str, help=argparse.SUPPRESS) # help="(required) path to input image file or directory (you should use the full path)")
|
||||
parser.add_argument("--version", action="store_true", help="Displays version information and exits.")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# self.driver_settings['scale-ratio'] = upscaler.scale_ratio
|
||||
self.driver_settings['jobs'] = upscaler.processes
|
||||
self.driver_settings['output-format'] = upscaler.extracted_frame_format.lower()
|
||||
self.driver_settings["jobs"] = upscaler.processes
|
||||
self.driver_settings["output-format"] = upscaler.extracted_frame_format.lower()
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: float):
|
||||
self.driver_settings['scale-ratio'] = scale_ratio
|
||||
self.driver_settings["scale-ratio"] = scale_ratio
|
||||
|
||||
def upscale(self, input_directory, output_directory):
|
||||
""" Waifu2x Converter Driver Upscaler
|
||||
"""Waifu2x Converter Driver Upscaler
|
||||
This method executes the upscaling of extracted frames.
|
||||
|
||||
Arguments:
|
||||
@@ -87,33 +89,35 @@ class WrapperMain:
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['input'] = input_directory
|
||||
self.driver_settings['output'] = output_directory
|
||||
self.driver_settings["input"] = input_directory
|
||||
self.driver_settings["output"] = output_directory
|
||||
|
||||
# models_rgb must be specified manually for waifu2x-converter-cpp
|
||||
# if it's not specified in the arguments, create automatically
|
||||
if self.driver_settings['model-dir'] is None:
|
||||
self.driver_settings['model-dir'] = pathlib.Path(self.driver_settings['path']).parent / 'models_rgb'
|
||||
if self.driver_settings["model-dir"] is None:
|
||||
self.driver_settings["model-dir"] = (
|
||||
pathlib.Path(self.driver_settings["path"]).parent / "models_rgb"
|
||||
)
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with waifu2x binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -121,6 +125,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
@@ -41,32 +41,36 @@ class WrapperMain:
|
||||
|
||||
@staticmethod
|
||||
def parse_arguments(arguments):
|
||||
# fmt: off
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
|
||||
parser.error = lambda message: (_ for _ in ()).throw(AttributeError(message))
|
||||
parser.add_argument('--help', action='help', help='show this help message and exit')
|
||||
parser.add_argument('-v', action='store_true', help='verbose output')
|
||||
parser.add_argument('-i', type=str, help=argparse.SUPPRESS) # help='input image path (jpg/png/webp) or directory')
|
||||
parser.add_argument('-o', type=str, help=argparse.SUPPRESS) # help='output image path (jpg/png/webp) or directory')
|
||||
parser.add_argument('-n', type=int, choices=range(-1, 4), help='denoise level')
|
||||
parser.add_argument('-s', type=int, help='upscale ratio')
|
||||
parser.add_argument('-t', type=int, help='tile size (>=32)')
|
||||
parser.add_argument('-m', type=str, help='waifu2x model path')
|
||||
parser.add_argument('-g', type=int, help='gpu device to use')
|
||||
parser.add_argument('-j', type=str, help='thread count for load/proc/save')
|
||||
parser.add_argument('-x', action='store_true', help='enable tta mode')
|
||||
parser.add_argument('-f', type=str, help=argparse.SUPPRESS) # help='output image format (jpg/png/webp, default=ext/png)')
|
||||
parser.add_argument("--help", action="help", help="show this help message and exit")
|
||||
parser.add_argument("-v", action="store_true", help="verbose output")
|
||||
parser.add_argument("-i", type=str, help=argparse.SUPPRESS) # help="input image path (jpg/png/webp) or directory")
|
||||
parser.add_argument("-o", type=str, help=argparse.SUPPRESS) # help="output image path (jpg/png/webp) or directory")
|
||||
parser.add_argument("-n", type=int, choices=range(-1, 4), help="denoise level")
|
||||
parser.add_argument("-s", type=int, help="upscale ratio")
|
||||
parser.add_argument("-t", type=int, help="tile size (>=32)")
|
||||
parser.add_argument("-m", type=str, help="waifu2x model path")
|
||||
parser.add_argument("-g", type=int, help="gpu device to use")
|
||||
parser.add_argument("-j", type=str, help="thread count for load/proc/save")
|
||||
parser.add_argument("-x", action="store_true", help="enable tta mode")
|
||||
parser.add_argument("-f", type=str, help=argparse.SUPPRESS) # help="output image format (jpg/png/webp, default=ext/png)")
|
||||
return parser.parse_args(arguments)
|
||||
# fmt: on
|
||||
|
||||
def load_configurations(self, upscaler):
|
||||
# self.driver_settings['s'] = int(upscaler.scale_ratio)
|
||||
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
|
||||
self.driver_settings['f'] = upscaler.extracted_frame_format.lower()
|
||||
self.driver_settings["j"] = "{}:{}:{}".format(
|
||||
upscaler.processes, upscaler.processes, upscaler.processes
|
||||
)
|
||||
self.driver_settings["f"] = upscaler.extracted_frame_format.lower()
|
||||
|
||||
def set_scale_ratio(self, scale_ratio: int):
|
||||
self.driver_settings['s'] = int(scale_ratio)
|
||||
self.driver_settings["s"] = int(scale_ratio)
|
||||
|
||||
def upscale(self, input_directory, output_directory):
|
||||
""" This is the core function for waifu2x class
|
||||
"""This is the core function for waifu2x class
|
||||
|
||||
Arguments:
|
||||
input_directory {string} -- source directory path
|
||||
@@ -76,33 +80,33 @@ class WrapperMain:
|
||||
|
||||
# change the working directory to the binary's parent directory
|
||||
# so the binary can find shared object files and other files
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# overwrite config file settings
|
||||
self.driver_settings['i'] = input_directory
|
||||
self.driver_settings['o'] = output_directory
|
||||
self.driver_settings["i"] = input_directory
|
||||
self.driver_settings["o"] = output_directory
|
||||
|
||||
# by default, waifu2x-ncnn-vulkan will look for the models under the current working directory
|
||||
# change the working directory to its containing folder if model directory not specified
|
||||
if self.driver_settings['m'] is None and platform.system() == 'Windows':
|
||||
os.chdir(pathlib.Path(self.driver_settings['path']).parent)
|
||||
if self.driver_settings["m"] is None and platform.system() == "Windows":
|
||||
os.chdir(pathlib.Path(self.driver_settings["path"]).parent)
|
||||
|
||||
# list to be executed
|
||||
# initialize the list with waifu2x binary path as the first element
|
||||
execute = [self.driver_settings['path']]
|
||||
execute = [self.driver_settings["path"]]
|
||||
|
||||
for key in self.driver_settings.keys():
|
||||
|
||||
value = self.driver_settings[key]
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
if key == 'path' or value is None or value is False:
|
||||
if key == "path" or value is None or value is False:
|
||||
continue
|
||||
else:
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
execute.append(f"-{key}")
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(f"--{key}")
|
||||
|
||||
# true means key is an option
|
||||
if value is not True:
|
||||
@@ -110,6 +114,8 @@ class WrapperMain:
|
||||
|
||||
# return the Popen object of the new process created
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}')
|
||||
Avalon.debug_info(
|
||||
f'[upscaler] Subprocess {os.getpid()} executing: {" ".join(execute)}'
|
||||
)
|
||||
self.print_lock.release()
|
||||
return subprocess.Popen(execute, stdout=sys.stdout, stderr=sys.stderr)
|
||||
|
||||
Reference in New Issue
Block a user