added arbitrary upscaling ratio/resolution support

This commit is contained in:
K4YT3X 2020-09-09 13:07:42 -04:00
parent 8b7e9f959b
commit 7059852586
16 changed files with 576 additions and 380 deletions

View File

@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"POT-Creation-Date: 2020-05-22 17:51-0400\n" "POT-Creation-Date: 2020-09-09 13:04-0400\n"
"PO-Revision-Date: 2020-05-22 17:54-0400\n" "PO-Revision-Date: 2020-09-09 13:06-0400\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: zh_CN\n" "Language: zh_CN\n"
@ -14,234 +14,230 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.3.1\n" "X-Generator: Poedit 2.4.1\n"
"Plural-Forms: nplurals=1; plural=0;\n" "Plural-Forms: nplurals=1; plural=0;\n"
#: progress_monitor.py:42 #: progress_monitor.py:37
msgid "Upscaling Progress" msgid "Processing: {} (pass {}/{})"
msgstr "放大进度" msgstr "正在处理:{}(进度)"
#: upscaler.py:110 #: upscaler.py:144
msgid "Specified or default cache directory is a file/link" msgid "Specified or default cache directory is a file/link"
msgstr "指定或默认的缓存目录是文件/链接" msgstr "指定或默认的缓存目录是文件/链接"
#: upscaler.py:116 #: upscaler.py:150
msgid "Creating cache directory {}" msgid "Creating cache directory {}"
msgstr "创建缓存目录 {}" msgstr "创建缓存目录 {}"
#: upscaler.py:119 #: upscaler.py:153
msgid "Unable to create {}" msgid "Unable to create {}"
msgstr "无法创建 {}" msgstr "无法创建 {}"
#: upscaler.py:124 #: upscaler.py:158
msgid "Extracted frames are being saved to: {}" msgid "Extracted frames are being saved to: {}"
msgstr "提取的帧将被保存到:{}" msgstr "提取的帧将被保存到:{}"
#: upscaler.py:126 #: upscaler.py:160
msgid "Upscaled frames are being saved to: {}" msgid "Upscaled frames are being saved to: {}"
msgstr "已放大的帧将被保存到:{}" msgstr "已放大的帧将被保存到:{}"
#: upscaler.py:136 #: upscaler.py:170
msgid "Cleaning up cache directory: {}" msgid "Cleaning up cache directory: {}"
msgstr "清理缓存目录:{}" msgstr "清理缓存目录:{}"
#: upscaler.py:141 #: upscaler.py:175
msgid "Unable to delete: {}" msgid "Unable to delete: {}"
msgstr "无法删除:{}" msgstr "无法删除:{}"
#: upscaler.py:147 upscaler.py:162 upscaler.py:173 #: upscaler.py:181 upscaler.py:196 upscaler.py:207
msgid "Input and output path type mismatch" msgid "Input and output path type mismatch"
msgstr "输入和输出路径类型不匹配" msgstr "输入和输出路径类型不匹配"
#: upscaler.py:148 #: upscaler.py:182
msgid "Input is multiple files but output is not directory" msgid "Input is multiple files but output is not directory"
msgstr "输入是多个文件,但输出不是目录" msgstr "输入是多个文件,但输出不是目录"
#: upscaler.py:152 #: upscaler.py:186
msgid "Input path {} is neither a file nor a directory" msgid "Input path {} is neither a file nor a directory"
msgstr "输入路径 {} 既不是文件也不是目录" msgstr "输入路径 {} 既不是文件也不是目录"
#: upscaler.py:156 upscaler.py:178 #: upscaler.py:190 upscaler.py:212
msgid "Input directory and output directory cannot be the same" msgid "Input directory and output directory cannot be the same"
msgstr "输入目录和输出目录不能相同" msgstr "输入目录和输出目录不能相同"
#: upscaler.py:163 #: upscaler.py:197
msgid "Input is single file but output is directory" msgid "Input is single file but output is directory"
msgstr "所选的输入路径是单个文件,但输出路径是目录" msgstr "所选的输入路径是单个文件,但输出路径是目录"
#: upscaler.py:166 #: upscaler.py:200
msgid "No suffix found in output file path" msgid "No suffix found in output file path"
msgstr "在输出文件路径中未找到后缀" msgstr "在输出文件路径中未找到后缀"
#: upscaler.py:167 #: upscaler.py:201
msgid "Suffix must be specified" msgid "Suffix must be specified"
msgstr "必须指定文件后缀" msgstr "必须指定文件后缀"
#: upscaler.py:174 #: upscaler.py:208
msgid "Input is directory but output is existing single file" msgid "Input is directory but output is existing single file"
msgstr "输入是目录,但输出是现有的单个文件" msgstr "输入是目录,但输出是现有的单个文件"
#: upscaler.py:183 #: upscaler.py:217
msgid "Input path is neither a file nor a directory" msgid "Input path is neither a file nor a directory"
msgstr "输入路径既不是文件也不是目录" msgstr "输入路径既不是文件也不是目录"
#: upscaler.py:192 #: upscaler.py:226
msgid "FFmpeg or FFprobe cannot be found under the specified path" msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe" msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe"
#: upscaler.py:193 upscaler.py:203 #: upscaler.py:227 upscaler.py:237
msgid "Please check the configuration file settings" msgid "Please check the configuration file settings"
msgstr "请检查配置文件设置" msgstr "请检查配置文件设置"
#: upscaler.py:202 #: upscaler.py:236
msgid "Specified driver executable directory doesn't exist" msgid "Specified driver executable directory doesn't exist"
msgstr "指定驱动的可执行文件不存在" msgstr "指定驱动的可执行文件不存在"
#: upscaler.py:229 #: upscaler.py:263
msgid "Failed to parse driver argument: {}" msgid "Failed to parse driver argument: {}"
msgstr "解析驱动程序参数失败:{}" msgstr "解析驱动程序参数失败:{}"
#: upscaler.py:261 #: upscaler.py:283
msgid "Unrecognized driver: {}" msgid "Unrecognized driver: {}"
msgstr "无法识别的驱动名称:{}" msgstr "无法识别的驱动名称:{}"
#: upscaler.py:301 #: upscaler.py:323
msgid "Starting progress monitor" msgid "Starting progress monitor"
msgstr "启动进度监视器" msgstr "启动进度监视器"
#: upscaler.py:306 #: upscaler.py:328
msgid "Starting upscaled image cleaner" msgid "Starting upscaled image cleaner"
msgstr "启动已放大图像清理程序" msgstr "启动已放大图像清理程序"
#: upscaler.py:315 upscaler.py:332 #: upscaler.py:337 upscaler.py:354
msgid "Killing progress monitor" msgid "Killing progress monitor"
msgstr "终结进度监视器" msgstr "终结进度监视器"
#: upscaler.py:318 upscaler.py:335 #: upscaler.py:340 upscaler.py:357
msgid "Killing upscaled image cleaner" msgid "Killing upscaled image cleaner"
msgstr "终结已放大图像清理程序" msgstr "终结已放大图像清理程序"
#: upscaler.py:339 #: upscaler.py:361
msgid "Terminating all processes" msgid "Terminating all processes"
msgstr "正在终止所有进程" msgstr "正在终止所有进程"
#: upscaler.py:346 #: upscaler.py:368
msgid "Main process waiting for subprocesses to exit" msgid "Main process waiting for subprocesses to exit"
msgstr "主进程开始等待子进程结束" msgstr "主进程开始等待子进程结束"
#: upscaler.py:365 upscaler.py:369 #: upscaler.py:387 upscaler.py:391
msgid "Subprocess {} exited with code {}" msgid "Subprocess {} exited with code {}"
msgstr "子进程 {} 结束,返回码 {}" msgstr "子进程 {} 结束,返回码 {}"
#: upscaler.py:375 #: upscaler.py:397
msgid "Stop signal received" msgid "Stop signal received"
msgstr "收到停止信号" msgstr "收到停止信号"
#: upscaler.py:380 #: upscaler.py:402
msgid "Subprocess execution ran into an error" msgid "Subprocess execution ran into an error"
msgstr "子进程执行遇到错误" msgstr "子进程执行遇到错误"
#: upscaler.py:410 #: upscaler.py:432
msgid "Loading files into processing queue" msgid "Loading files into processing queue"
msgstr "正在将文件添加到处理队列中" msgstr "正在将文件添加到处理队列中"
#: upscaler.py:415 #: upscaler.py:433
msgid "Loading files from multiple paths"
msgstr "正在从多个路径中导入文件"
#: upscaler.py:416 upscaler.py:435 upscaler.py:442
msgid "Input path(s): {}" msgid "Input path(s): {}"
msgstr "输入路径:{}" msgstr "输入路径:{}"
#: upscaler.py:434 #: upscaler.py:495
msgid "Loading single file"
msgstr "正在导入单个文件"
#: upscaler.py:441
msgid "Loading files from directory"
msgstr "正在从文件夹中导入文件"
#: upscaler.py:455
msgid "Loaded files into processing queue"
msgstr "文件已添加到处理队列"
#: upscaler.py:458
msgid "Input file: {}"
msgstr "输入文件:{}"
#: upscaler.py:485
msgid "Starting to upscale image"
msgstr "开始放大图像"
#: upscaler.py:488 upscaler.py:550
msgid "Upscaling completed"
msgstr "放大完成"
#: upscaler.py:502
msgid "Reading video information"
msgstr "读取视频信息"
#: upscaler.py:516
msgid "Aborting: No video stream found"
msgstr "程序中止:文件中未找到视频流"
#: upscaler.py:521
msgid "Framerate: {}"
msgstr "帧率:{}"
#: upscaler.py:538
msgid "Unsupported pixel format: {}"
msgstr "不支持的像素格式:{}"
#: upscaler.py:548
msgid "Starting to upscale extracted frames"
msgstr "开始对提取的帧进行放大"
#: upscaler.py:555
msgid "File {} ({}) neither an image nor a video" msgid "File {} ({}) neither an image nor a video"
msgstr "文件 {} {} 既不是图片也不是视频" msgstr "文件 {} {} 既不是图片也不是视频"
#: upscaler.py:556 #: upscaler.py:496
msgid "Skipping this file" msgid "Skipping this file"
msgstr "将跳过此文件" msgstr "将跳过此文件"
#: upscaler.py:566 #: upscaler.py:521
msgid "Loaded files into processing queue"
msgstr "文件已添加到处理队列"
#: upscaler.py:524
msgid "Input file: {}"
msgstr "输入文件:{}"
#: upscaler.py:535
msgid "Starting to upscale image"
msgstr "开始放大图像"
#: upscaler.py:538 upscaler.py:689
msgid "Upscaling completed"
msgstr "放大完成"
#: upscaler.py:552
msgid "Reading video information"
msgstr "读取视频信息"
#: upscaler.py:564
msgid "Aborting: No video stream found"
msgstr "程序中止:文件中未找到视频流"
#: upscaler.py:571
msgid "Framerate: {}"
msgstr "帧率:{}"
#: upscaler.py:575
msgid "Getting total number of frames in the file"
msgstr "正在获取文件中的总帧数"
#: upscaler.py:650
msgid "Upscaling jobs queue: {}"
msgstr "放大工作队列:{}"
#: upscaler.py:666
msgid "Unsupported pixel format: {}"
msgstr "不支持的像素格式:{}"
#: upscaler.py:676
msgid "Starting to upscale extracted frames"
msgstr "开始对提取的帧进行放大"
#: upscaler.py:696
msgid "Converting extracted frames into GIF image" msgid "Converting extracted frames into GIF image"
msgstr "正在将提取的帧转换为 GIF" msgstr "正在将提取的帧转换为 GIF"
#: upscaler.py:570 upscaler.py:579 #: upscaler.py:700 upscaler.py:709
msgid "Conversion completed" msgid "Conversion completed"
msgstr "转换已完成" msgstr "转换已完成"
#: upscaler.py:575 #: upscaler.py:705
msgid "Converting extracted frames into video" msgid "Converting extracted frames into video"
msgstr "正在将提取的帧转换为视频" msgstr "正在将提取的帧转换为视频"
#: upscaler.py:583 #: upscaler.py:713
msgid "Migrating audio, subtitles and other streams to upscaled video" msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr "正在将音频、字幕和其他流迁移到放大后的视频" msgstr "正在将音频、字幕和其他流迁移到放大后的视频"
#: upscaler.py:593 #: upscaler.py:723
msgid "Failed to migrate streams" msgid "Failed to migrate streams"
msgstr "迁移流失败" msgstr "迁移流失败"
#: upscaler.py:594 #: upscaler.py:724
msgid "Trying to output video without additional streams" msgid "Trying to output video without additional streams"
msgstr "正在尝试输出不含其他流的视频" msgstr "正在尝试输出不含其他流的视频"
#: upscaler.py:610 #: upscaler.py:740
msgid "Output video file exists" msgid "Output video file exists"
msgstr "输出目标文件已存在" msgstr "输出目标文件已存在"
#: upscaler.py:614 #: upscaler.py:744
msgid "Created temporary directory to contain file" msgid "Created temporary directory to contain file"
msgstr "为文件创建了临时目录" msgstr "为文件创建了临时目录"
#: upscaler.py:617 #: upscaler.py:747
msgid "Writing intermediate file to: {}" msgid "Writing intermediate file to: {}"
msgstr "正在将中间视频文件写入至:{}" msgstr "正在将中间视频文件写入至:{}"
#: video2x.py:85 #: video2x.py:86
msgid "" msgid ""
"Video2X CLI Version: {}\n" "Video2X CLI Version: {}\n"
"Upscaler Version: {}\n" "Upscaler Version: {}\n"
@ -257,74 +253,108 @@ msgstr ""
"GitHub 主页https://github.com/k4yt3x/video2x\n" "GitHub 主页https://github.com/k4yt3x/video2x\n"
"联系方式k4yt3x@k4yt3x.com" "联系方式k4yt3x@k4yt3x.com"
#: video2x.py:108 #: video2x.py:109
msgid "Video2X Options" msgid "Video2X Options"
msgstr "Video2X 选项" msgstr "Video2X 选项"
#: video2x.py:109 #: video2x.py:110
msgid "show this help message and exit" msgid "show this help message and exit"
msgstr "显示此帮助消息并退出" msgstr "显示此帮助消息并退出"
#: video2x.py:110 #: video2x.py:117
msgid "source video file/directory" msgid "source video file/directory"
msgstr "源视频文件/目录" msgstr "源视频文件/目录"
#: video2x.py:111 #: video2x.py:118
msgid "output video file/directory" msgid "output video file/directory"
msgstr "输出视频文件/目录" msgstr "输出视频文件/目录"
#: video2x.py:112 #: video2x.py:120
msgid "video2x config file path" msgid "video2x config file path"
msgstr "video2x 配置文件路径" msgstr "video2x 配置文件路径"
#: video2x.py:114 #: video2x.py:122
msgid "log file path"
msgstr "日志文件路径"
#: video2x.py:124
msgid "disable logging"
msgstr "禁用日志"
#: video2x.py:125
msgid "display version, lawful information and exit" msgid "display version, lawful information and exit"
msgstr "显示版本和法律信息并退出" msgstr "显示版本和法律信息并退出"
#: video2x.py:117 #: video2x.py:128
msgid "Upscaling Options" msgid "Upscaling Options"
msgstr "视频放大选项" msgstr "视频放大选项"
#: video2x.py:118 #: video2x.py:129
msgid "upscaling driver"
msgstr "视频放大驱动"
#: video2x.py:119
msgid "scaling ratio" msgid "scaling ratio"
msgstr "缩放比" msgstr "缩放比"
#: video2x.py:120 #: video2x.py:130
msgid "output width"
msgstr "输出宽度"
#: video2x.py:131
msgid "output height"
msgstr "输出高度"
#: video2x.py:132
msgid "upscaling driver"
msgstr "视频放大驱动"
#: video2x.py:133
msgid "number of processes to use for upscaling" msgid "number of processes to use for upscaling"
msgstr "并发进程数" msgstr "并发进程数"
#: video2x.py:121 #: video2x.py:134
msgid "preserve extracted and upscaled frames" msgid "preserve extracted and upscaled frames"
msgstr "保留提取的和放大的帧" msgstr "保留提取的和放大的帧"
#: video2x.py:161 #: video2x.py:174
msgid "This file cannot be imported" msgid "This file cannot be imported"
msgstr "此文件无法被当作模块导入" msgstr "此文件无法被当作模块导入"
#: video2x.py:236 #: video2x.py:190
msgid "Specify either scaling ratio or scaling resolution, not both"
msgstr "您只能指定缩放比或输出分辨率两者之一"
#: video2x.py:194
msgid "Only one of scaling width and scaling height is specified"
msgstr "输出高度和宽度仅有其中一项被指定"
#: video2x.py:200
msgid "Redirecting console logs to {}"
msgstr "将控制台日志重定向到 {}"
#: video2x.py:276
msgid "Program completed, taking {} seconds" msgid "Program completed, taking {} seconds"
msgstr "程序执行完毕,总计花费 {} 秒" msgstr "程序执行完毕,总计花费 {} 秒"
#: video2x.py:239 #: video2x.py:279
msgid "An exception has occurred" msgid "An exception has occurred"
msgstr "发生了异常" msgstr "发生了异常"
#~ msgid "Upscaling Progress"
#~ msgstr "放大进度"
#~ msgid "Loading files from multiple paths"
#~ msgstr "正在从多个路径中导入文件"
#~ msgid "Loading single file"
#~ msgstr "正在导入单个文件"
#~ msgid "Loading files from directory"
#~ msgstr "正在从文件夹中导入文件"
#~ msgid "Anime4KCPP doesn't yet support GIF processing" #~ msgid "Anime4KCPP doesn't yet support GIF processing"
#~ msgstr "Anime4KCPP 尚不支持GIF处理" #~ msgstr "Anime4KCPP 尚不支持GIF处理"
#~ msgid "Starting to upscale video with Anime4KCPP" #~ msgid "Starting to upscale video with Anime4KCPP"
#~ msgstr "开始用 Anime4KCPP 放大视频" #~ msgstr "开始用 Anime4KCPP 放大视频"
#~ msgid "output video width"
#~ msgstr "输出视频宽度"
#~ msgid "output video height"
#~ msgstr "输出视频高度"
#~ msgid "You must specify input video file/directory path" #~ msgid "You must specify input video file/directory path"
#~ msgstr "您必须指定输入视频文件/目录路径" #~ msgstr "您必须指定输入视频文件/目录路径"
@ -340,8 +370,5 @@ msgstr "发生了异常"
#~ msgid "Scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan" #~ msgid "Scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan"
#~ msgstr "srmd_ncnn_vulkan 的缩放比必须为 2、3 或 4" #~ msgstr "srmd_ncnn_vulkan 的缩放比必须为 2、3 或 4"
#~ msgid "You can only specify either scaling ratio or output width and height"
#~ msgstr "您只能指定缩放比或输出宽度和高度两者之一"
#~ msgid "You must specify both width and height" #~ msgid "You must specify both width and height"
#~ msgstr "您必须同时指定宽度和高度" #~ msgstr "您必须同时指定宽度和高度"

View File

@ -4,7 +4,7 @@
Name: Video2X Upscale Progress Monitor Name: Video2X Upscale Progress Monitor
Author: K4YT3X Author: K4YT3X
Date Created: May 7, 2020 Date Created: May 7, 2020
Last Modified: June 7, 2020 Last Modified: September 9, 2020
""" """
# built-in imports # built-in imports
@ -34,12 +34,7 @@ class ProgressMonitor(threading.Thread):
def run(self): def run(self):
self.running = True self.running = True
# get number of extracted frames with tqdm(total=self.upscaler.total_frames, ascii=True, desc=_('Processing: {} (pass {}/{})').format(self.upscaler.current_input_file.name, self.upscaler.current_pass, len(self.upscaler.scaling_jobs))) as progress_bar:
self.upscaler.total_frames = 0
for directory in self.extracted_frames_directories:
self.upscaler.total_frames += len([f for f in directory.iterdir() if str(f).lower().endswith(self.upscaler.extracted_frame_format.lower())])
with tqdm(total=self.upscaler.total_frames, ascii=True, desc=_('Upscaling Progress')) as progress_bar:
# tqdm update method adds the value to the progress # tqdm update method adds the value to the progress
# bar instead of setting the value. Therefore, a delta # bar instead of setting the value. Therefore, a delta
# needs to be calculated. # needs to be calculated.

View File

@ -4,7 +4,7 @@
Name: Video2X Upscaler Name: Video2X Upscaler
Author: K4YT3X Author: K4YT3X
Date Created: December 10, 2018 Date Created: December 10, 2018
Last Modified: June 29, 2020 Last Modified: September 9, 2020
Description: This file contains the Upscaler class. Each Description: This file contains the Upscaler class. Each
instance of the Upscaler class is an upscaler on an image or instance of the Upscaler class is an upscaler on an image or
@ -25,6 +25,7 @@ import copy
import gettext import gettext
import importlib import importlib
import locale import locale
import math
import mimetypes import mimetypes
import pathlib import pathlib
import queue import queue
@ -50,7 +51,7 @@ language.install()
_ = language.gettext _ = language.gettext
# version information # version information
UPSCALER_VERSION = '4.2.2' UPSCALER_VERSION = '4.3.0'
# these names are consistent for # these names are consistent for
# - driver selection in command line # - driver selection in command line
@ -63,6 +64,12 @@ AVAILABLE_DRIVERS = ['waifu2x_caffe',
'realsr_ncnn_vulkan', 'realsr_ncnn_vulkan',
'anime4kcpp'] 'anime4kcpp']
DRIVER_FIXED_SCALING_RATIOS = {
'waifu2x_ncnn_vulkan': [1, 2],
'srmd_ncnn_vulkan': [2, 3, 4],
'realsr_ncnn_vulkan': [4],
}
class Upscaler: class Upscaler:
""" An instance of this class is a upscaler that will """ An instance of this class is a upscaler that will
@ -82,6 +89,8 @@ class Upscaler:
gifski_settings: dict, gifski_settings: dict,
driver: str = 'waifu2x_caffe', driver: str = 'waifu2x_caffe',
scale_ratio: float = None, scale_ratio: float = None,
scale_width: int = None,
scale_height: int = None,
processes: int = 1, processes: int = 1,
video2x_cache_directory: pathlib.Path = pathlib.Path(tempfile.gettempdir()) / 'video2x', video2x_cache_directory: pathlib.Path = pathlib.Path(tempfile.gettempdir()) / 'video2x',
extracted_frame_format: str = 'png', extracted_frame_format: str = 'png',
@ -101,6 +110,8 @@ class Upscaler:
# optional parameters # optional parameters
self.driver = driver self.driver = driver
self.scale_ratio = scale_ratio self.scale_ratio = scale_ratio
self.scale_width = scale_width
self.scale_height = scale_height
self.processes = processes self.processes = processes
self.video2x_cache_directory = video2x_cache_directory self.video2x_cache_directory = video2x_cache_directory
self.extracted_frame_format = extracted_frame_format self.extracted_frame_format = extracted_frame_format
@ -115,6 +126,8 @@ class Upscaler:
self.total_frames = 0 self.total_frames = 0
self.total_files = 0 self.total_files = 0
self.total_processed = 0 self.total_processed = 0
self.scaling_jobs = []
self.current_pass = 0
self.current_input_file = pathlib.Path() self.current_input_file = pathlib.Path()
self.last_frame_upscaled = pathlib.Path() self.last_frame_upscaled = pathlib.Path()
@ -250,31 +263,19 @@ class Upscaler:
Avalon.error(_('Failed to parse driver argument: {}').format(e.args[0])) Avalon.error(_('Failed to parse driver argument: {}').format(e.args[0]))
raise e raise e
# waifu2x-caffe scale_ratio, scale_width and scale_height check def _upscale_frames(self, input_directory: pathlib.Path, output_directory: pathlib.Path):
if self.driver == 'waifu2x_caffe':
if (driver_settings['scale_width'] != 0 and driver_settings['scale_height'] == 0 or
driver_settings['scale_width'] == 0 and driver_settings['scale_height'] != 0):
Avalon.error(_('Only one of scale_width and scale_height is specified for waifu2x-caffe'))
raise AttributeError('only one of scale_width and scale_height is specified for waifu2x-caffe')
# if scale_width and scale_height are specified, ensure scale_ratio is None
elif self.driver_settings['scale_width'] != 0 and self.driver_settings['scale_height'] != 0:
self.driver_settings['scale_ratio'] = None
# if scale_width and scale_height not specified
# ensure they are None, not 0
else:
self.driver_settings['scale_width'] = None
self.driver_settings['scale_height'] = None
def _upscale_frames(self):
""" Upscale video frames with waifu2x-caffe """ Upscale video frames with waifu2x-caffe
This function upscales all the frames extracted This function upscales all the frames extracted
by ffmpeg using the waifu2x-caffe binary. by ffmpeg using the waifu2x-caffe binary.
Arguments: Args:
w2 {Waifu2x Object} -- initialized waifu2x object input_directory (pathlib.Path): directory containing frames to upscale
output_directory (pathlib.Path): directory which upscaled frames should be exported to
Raises:
UnrecognizedDriverError: raised when the given driver is not recognized
e: re-raised exception after an exception has been captured and finished processing in this scope
""" """
# initialize waifu2x driver # initialize waifu2x driver
@ -282,7 +283,7 @@ class Upscaler:
raise UnrecognizedDriverError(_('Unrecognized driver: {}').format(self.driver)) raise UnrecognizedDriverError(_('Unrecognized driver: {}').format(self.driver))
# list all images in the extracted frames # list all images in the extracted frames
frames = [(self.extracted_frames / f) for f in self.extracted_frames.iterdir() if f.is_file] frames = [(input_directory / f) for f in input_directory.iterdir() if f.is_file]
# if we have less images than processes, # if we have less images than processes,
# create only the processes necessary # create only the processes necessary
@ -293,7 +294,7 @@ class Upscaler:
# name into a list # name into a list
process_directories = [] process_directories = []
for process_id in range(self.processes): for process_id in range(self.processes):
process_directory = self.extracted_frames / str(process_id) process_directory = input_directory / str(process_id)
process_directories.append(process_directory) process_directories.append(process_directory)
# delete old directories and create new directories # delete old directories and create new directories
@ -303,7 +304,7 @@ class Upscaler:
# waifu2x-converter-cpp will perform multi-threading within its own process # waifu2x-converter-cpp will perform multi-threading within its own process
if self.driver in ['waifu2x_converter_cpp', 'waifu2x_ncnn_vulkan', 'srmd_ncnn_vulkan', 'realsr_ncnn_vulkan', 'anime4kcpp']: if self.driver in ['waifu2x_converter_cpp', 'waifu2x_ncnn_vulkan', 'srmd_ncnn_vulkan', 'realsr_ncnn_vulkan', 'anime4kcpp']:
process_directories = [self.extracted_frames] process_directories = [input_directory]
else: else:
# evenly distribute images into each directory # evenly distribute images into each directory
@ -316,7 +317,7 @@ class Upscaler:
# create driver processes and start them # create driver processes and start them
for process_directory in process_directories: for process_directory in process_directories:
self.process_pool.append(self.driver_object.upscale(process_directory, self.upscaled_frames)) self.process_pool.append(self.driver_object.upscale(process_directory, output_directory))
# start progress bar in a different thread # start progress bar in a different thread
Avalon.debug_info(_('Starting progress monitor')) Avalon.debug_info(_('Starting progress monitor'))
@ -325,7 +326,7 @@ class Upscaler:
# create the clearer and start it # create the clearer and start it
Avalon.debug_info(_('Starting upscaled image cleaner')) Avalon.debug_info(_('Starting upscaled image cleaner'))
self.image_cleaner = ImageCleaner(self.extracted_frames, self.upscaled_frames, len(self.process_pool)) self.image_cleaner = ImageCleaner(input_directory, output_directory, len(self.process_pool))
self.image_cleaner.start() self.image_cleaner.start()
# wait for all process to exit # wait for all process to exit
@ -343,11 +344,11 @@ class Upscaler:
# if the driver is waifu2x-converter-cpp # if the driver is waifu2x-converter-cpp
# images need to be renamed to be recognizable for FFmpeg # images need to be renamed to be recognizable for FFmpeg
if self.driver == 'waifu2x_converter_cpp': if self.driver == 'waifu2x_converter_cpp':
for image in [f for f in self.upscaled_frames.iterdir() if f.is_file()]: for image in [f for f in output_directory.iterdir() if f.is_file()]:
renamed = re.sub(f'_\\[.*\\]\\[x(\\d+(\\.\\d+)?)\\]\\.{self.extracted_frame_format}', renamed = re.sub(f'_\\[.*\\]\\[x(\\d+(\\.\\d+)?)\\]\\.{self.extracted_frame_format}',
f'.{self.extracted_frame_format}', f'.{self.extracted_frame_format}',
str(image.name)) str(image.name))
(self.upscaled_frames / image).rename(self.upscaled_frames / renamed) (output_directory / image).rename(output_directory / renamed)
# upscaling done, kill helper threads # upscaling done, kill helper threads
Avalon.debug_info(_('Killing progress monitor')) Avalon.debug_info(_('Killing progress monitor'))
@ -550,8 +551,6 @@ class Upscaler:
# get video information JSON using FFprobe # get video information JSON using FFprobe
Avalon.info(_('Reading video information')) Avalon.info(_('Reading video information'))
video_info = self.ffmpeg_object.probe_file_info(self.current_input_file) video_info = self.ffmpeg_object.probe_file_info(self.current_input_file)
# analyze original video with FFprobe and retrieve framerate
# width, height = info['streams'][0]['width'], info['streams'][0]['height']
# find index of video stream # find index of video stream
video_stream_index = None video_stream_index = None
@ -567,9 +566,89 @@ class Upscaler:
# get average frame rate of video stream # get average frame rate of video stream
framerate = float(Fraction(video_info['streams'][video_stream_index]['r_frame_rate'])) framerate = float(Fraction(video_info['streams'][video_stream_index]['r_frame_rate']))
width = int(video_info['streams'][video_stream_index]['width'])
height = int(video_info['streams'][video_stream_index]['height'])
Avalon.info(_('Framerate: {}').format(framerate)) Avalon.info(_('Framerate: {}').format(framerate))
# self.ffmpeg_object.pixel_format = video_info['streams'][video_stream_index]['pix_fmt'] # self.ffmpeg_object.pixel_format = video_info['streams'][video_stream_index]['pix_fmt']
# get total number of frames
Avalon.info(_('Getting total number of frames in the file'))
# if container stores total number of frames in nb_frames, fetch it directly
if 'nb_frames' in video_info['streams'][video_stream_index]:
self.total_frames = int(video_info['streams'][video_stream_index]['nb_frames'])
# otherwise call FFprobe to count the total number of frames
else:
self.total_frames = self.ffmpeg_object.get_number_of_frames(self.current_input_file, video_stream_index)
# if driver is one of the drivers that doesn't support arbitrary scaling ratio
# TODO: more documentations on this block
if self.driver in DRIVER_FIXED_SCALING_RATIOS:
# if user specified output resolution
# calculate number of passes needed
if self.scale_width is not None and self.scale_height is not None:
self.scale_ratio = 2
# when scaled output resolution is smaller than target output resolution
# increase scaling ratio
while (self.scale_ratio * width) < self.scale_width:
self.scale_ratio += 1
while (self.scale_ratio * height) < self.scale_height:
self.scale_ratio += 1
# select the optimal driver scaling ratio to use
supported_scaling_ratios = sorted(DRIVER_FIXED_SCALING_RATIOS[self.driver])
remaining_scaling_ratio = math.ceil(self.scale_ratio)
self.scaling_jobs = []
while remaining_scaling_ratio > 1:
for ratio in supported_scaling_ratios:
if ratio >= remaining_scaling_ratio:
self.scaling_jobs.append(ratio)
remaining_scaling_ratio /= ratio
break
else:
found = False
for i in supported_scaling_ratios:
for j in supported_scaling_ratios:
if i * j >= remaining_scaling_ratio:
self.scaling_jobs.extend([i, j])
remaining_scaling_ratio /= i * j
found = True
break
if found is True:
break
if found is False:
self.scaling_jobs.append(supported_scaling_ratios[-1])
remaining_scaling_ratio /= supported_scaling_ratios[-1]
# calculate and set output bicubic downscaling filter
# always ensure that the output resolution is divisible by 2
if self.scale_width is not None and self.scale_height is not None:
output_width = math.ceil(self.scale_width / 2.0) * 2
output_height = math.ceil(self.scale_height / 2.0) * 2
else:
output_width = math.ceil(width * self.scale_ratio / 2.0) * 2
output_height = math.ceil(height * self.scale_ratio / 2.0) * 2
# append scaling filter to video assembly command
if self.ffmpeg_settings['assemble_video']['output_options'].get('-vf') is None:
self.ffmpeg_settings['assemble_video']['output_options']['-vf'] = f'scale={output_width}:{output_height}'
else:
self.ffmpeg_settings['assemble_video']['output_options']['-vf'] += f',scale={output_width}:{output_height}'
else:
self.scaling_jobs = [self.scale_ratio]
Avalon.debug_info(_('Upscaling jobs queue: {}').format(self.scaling_jobs))
# extract frames from video # extract frames from video
self.process_pool.append((self.ffmpeg_object.extract_frames(self.current_input_file, self.extracted_frames))) self.process_pool.append((self.ffmpeg_object.extract_frames(self.current_input_file, self.extracted_frames)))
self._wait() self._wait()
@ -595,7 +674,18 @@ class Upscaler:
# upscale images one by one using waifu2x # upscale images one by one using waifu2x
Avalon.info(_('Starting to upscale extracted frames')) Avalon.info(_('Starting to upscale extracted frames'))
self._upscale_frames()
self.current_pass = 1
self.driver_object.set_scale_ratio(self.scaling_jobs[0])
self._upscale_frames(self.extracted_frames, self.upscaled_frames)
for job in self.scaling_jobs[1:]:
self.current_pass += 1
self.driver_object.set_scale_ratio(job)
shutil.rmtree(self.extracted_frames)
shutil.move(self.upscaled_frames, self.extracted_frames)
self.upscaled_frames.mkdir(parents=True, exist_ok=True)
self._upscale_frames(self.extracted_frames, self.upscaled_frames)
Avalon.info(_('Upscaling completed')) Avalon.info(_('Upscaling completed'))
# start handling output # start handling output

View File

@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2020-05-22 17:51-0400\n" "POT-Creation-Date: 2020-09-09 13:04-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -15,231 +15,227 @@ msgstr ""
"Generated-By: pygettext.py 1.5\n" "Generated-By: pygettext.py 1.5\n"
#: progress_monitor.py:42 #: progress_monitor.py:37
msgid "Upscaling Progress" msgid "Processing: {} (pass {}/{})"
msgstr "" msgstr ""
#: upscaler.py:110 #: upscaler.py:144
msgid "Specified or default cache directory is a file/link" msgid "Specified or default cache directory is a file/link"
msgstr "" msgstr ""
#: upscaler.py:116 #: upscaler.py:150
msgid "Creating cache directory {}" msgid "Creating cache directory {}"
msgstr "" msgstr ""
#: upscaler.py:119 #: upscaler.py:153
msgid "Unable to create {}" msgid "Unable to create {}"
msgstr "" msgstr ""
#: upscaler.py:124 #: upscaler.py:158
msgid "Extracted frames are being saved to: {}" msgid "Extracted frames are being saved to: {}"
msgstr "" msgstr ""
#: upscaler.py:126 #: upscaler.py:160
msgid "Upscaled frames are being saved to: {}" msgid "Upscaled frames are being saved to: {}"
msgstr "" msgstr ""
#: upscaler.py:136 #: upscaler.py:170
msgid "Cleaning up cache directory: {}" msgid "Cleaning up cache directory: {}"
msgstr "" msgstr ""
#: upscaler.py:141 #: upscaler.py:175
msgid "Unable to delete: {}" msgid "Unable to delete: {}"
msgstr "" msgstr ""
#: upscaler.py:147 upscaler.py:162 upscaler.py:173 #: upscaler.py:181 upscaler.py:196 upscaler.py:207
msgid "Input and output path type mismatch" msgid "Input and output path type mismatch"
msgstr "" msgstr ""
#: upscaler.py:148 #: upscaler.py:182
msgid "Input is multiple files but output is not directory" msgid "Input is multiple files but output is not directory"
msgstr "" msgstr ""
#: upscaler.py:152 #: upscaler.py:186
msgid "Input path {} is neither a file nor a directory" msgid "Input path {} is neither a file nor a directory"
msgstr "" msgstr ""
#: upscaler.py:156 upscaler.py:178 #: upscaler.py:190 upscaler.py:212
msgid "Input directory and output directory cannot be the same" msgid "Input directory and output directory cannot be the same"
msgstr "" msgstr ""
#: upscaler.py:163 #: upscaler.py:197
msgid "Input is single file but output is directory" msgid "Input is single file but output is directory"
msgstr "" msgstr ""
#: upscaler.py:166 #: upscaler.py:200
msgid "No suffix found in output file path" msgid "No suffix found in output file path"
msgstr "" msgstr ""
#: upscaler.py:167 #: upscaler.py:201
msgid "Suffix must be specified" msgid "Suffix must be specified"
msgstr "" msgstr ""
#: upscaler.py:174 #: upscaler.py:208
msgid "Input is directory but output is existing single file" msgid "Input is directory but output is existing single file"
msgstr "" msgstr ""
#: upscaler.py:183 #: upscaler.py:217
msgid "Input path is neither a file nor a directory" msgid "Input path is neither a file nor a directory"
msgstr "" msgstr ""
#: upscaler.py:192 #: upscaler.py:226
msgid "FFmpeg or FFprobe cannot be found under the specified path" msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr "" msgstr ""
#: upscaler.py:193 upscaler.py:203 #: upscaler.py:227 upscaler.py:237
msgid "Please check the configuration file settings" msgid "Please check the configuration file settings"
msgstr "" msgstr ""
#: upscaler.py:202 #: upscaler.py:236
msgid "Specified driver executable directory doesn't exist" msgid "Specified driver executable directory doesn't exist"
msgstr "" msgstr ""
#: upscaler.py:229 #: upscaler.py:263
msgid "Failed to parse driver argument: {}" msgid "Failed to parse driver argument: {}"
msgstr "" msgstr ""
#: upscaler.py:261 #: upscaler.py:283
msgid "Unrecognized driver: {}" msgid "Unrecognized driver: {}"
msgstr "" msgstr ""
#: upscaler.py:301 #: upscaler.py:323
msgid "Starting progress monitor" msgid "Starting progress monitor"
msgstr "" msgstr ""
#: upscaler.py:306 #: upscaler.py:328
msgid "Starting upscaled image cleaner" msgid "Starting upscaled image cleaner"
msgstr "" msgstr ""
#: upscaler.py:315 upscaler.py:332 #: upscaler.py:337 upscaler.py:354
msgid "Killing progress monitor" msgid "Killing progress monitor"
msgstr "" msgstr ""
#: upscaler.py:318 upscaler.py:335 #: upscaler.py:340 upscaler.py:357
msgid "Killing upscaled image cleaner" msgid "Killing upscaled image cleaner"
msgstr "" msgstr ""
#: upscaler.py:339 #: upscaler.py:361
msgid "Terminating all processes" msgid "Terminating all processes"
msgstr "" msgstr ""
#: upscaler.py:346 #: upscaler.py:368
msgid "Main process waiting for subprocesses to exit" msgid "Main process waiting for subprocesses to exit"
msgstr "" msgstr ""
#: upscaler.py:365 upscaler.py:369 #: upscaler.py:387 upscaler.py:391
msgid "Subprocess {} exited with code {}" msgid "Subprocess {} exited with code {}"
msgstr "" msgstr ""
#: upscaler.py:375 #: upscaler.py:397
msgid "Stop signal received" msgid "Stop signal received"
msgstr "" msgstr ""
#: upscaler.py:380 #: upscaler.py:402
msgid "Subprocess execution ran into an error" msgid "Subprocess execution ran into an error"
msgstr "" msgstr ""
#: upscaler.py:410 #: upscaler.py:432
msgid "Loading files into processing queue" msgid "Loading files into processing queue"
msgstr "" msgstr ""
#: upscaler.py:415 #: upscaler.py:433
msgid "Loading files from multiple paths"
msgstr ""
#: upscaler.py:416 upscaler.py:435 upscaler.py:442
msgid "Input path(s): {}" msgid "Input path(s): {}"
msgstr "" msgstr ""
#: upscaler.py:434 #: upscaler.py:495
msgid "Loading single file"
msgstr ""
#: upscaler.py:441
msgid "Loading files from directory"
msgstr ""
#: upscaler.py:455
msgid "Loaded files into processing queue"
msgstr ""
#: upscaler.py:458
msgid "Input file: {}"
msgstr ""
#: upscaler.py:485
msgid "Starting to upscale image"
msgstr ""
#: upscaler.py:488 upscaler.py:550
msgid "Upscaling completed"
msgstr ""
#: upscaler.py:502
msgid "Reading video information"
msgstr ""
#: upscaler.py:516
msgid "Aborting: No video stream found"
msgstr ""
#: upscaler.py:521
msgid "Framerate: {}"
msgstr ""
#: upscaler.py:538
msgid "Unsupported pixel format: {}"
msgstr ""
#: upscaler.py:548
msgid "Starting to upscale extracted frames"
msgstr ""
#: upscaler.py:555
msgid "File {} ({}) neither an image nor a video" msgid "File {} ({}) neither an image nor a video"
msgstr "" msgstr ""
#: upscaler.py:556 #: upscaler.py:496
msgid "Skipping this file" msgid "Skipping this file"
msgstr "" msgstr ""
#: upscaler.py:566 #: upscaler.py:521
msgid "Converting extracted frames into GIF image" msgid "Loaded files into processing queue"
msgstr "" msgstr ""
#: upscaler.py:570 upscaler.py:579 #: upscaler.py:524
msgid "Conversion completed" msgid "Input file: {}"
msgstr ""
#: upscaler.py:535
msgid "Starting to upscale image"
msgstr ""
#: upscaler.py:538 upscaler.py:689
msgid "Upscaling completed"
msgstr ""
#: upscaler.py:552
msgid "Reading video information"
msgstr ""
#: upscaler.py:564
msgid "Aborting: No video stream found"
msgstr ""
#: upscaler.py:571
msgid "Framerate: {}"
msgstr "" msgstr ""
#: upscaler.py:575 #: upscaler.py:575
msgid "Getting total number of frames in the file"
msgstr ""
#: upscaler.py:650
msgid "Upscaling jobs queue: {}"
msgstr ""
#: upscaler.py:666
msgid "Unsupported pixel format: {}"
msgstr ""
#: upscaler.py:676
msgid "Starting to upscale extracted frames"
msgstr ""
#: upscaler.py:696
msgid "Converting extracted frames into GIF image"
msgstr ""
#: upscaler.py:700 upscaler.py:709
msgid "Conversion completed"
msgstr ""
#: upscaler.py:705
msgid "Converting extracted frames into video" msgid "Converting extracted frames into video"
msgstr "" msgstr ""
#: upscaler.py:583 #: upscaler.py:713
msgid "Migrating audio, subtitles and other streams to upscaled video" msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr "" msgstr ""
#: upscaler.py:593 #: upscaler.py:723
msgid "Failed to migrate streams" msgid "Failed to migrate streams"
msgstr "" msgstr ""
#: upscaler.py:594 #: upscaler.py:724
msgid "Trying to output video without additional streams" msgid "Trying to output video without additional streams"
msgstr "" msgstr ""
#: upscaler.py:610 #: upscaler.py:740
msgid "Output video file exists" msgid "Output video file exists"
msgstr "" msgstr ""
#: upscaler.py:614 #: upscaler.py:744
msgid "Created temporary directory to contain file" msgid "Created temporary directory to contain file"
msgstr "" msgstr ""
#: upscaler.py:617 #: upscaler.py:747
msgid "Writing intermediate file to: {}" msgid "Writing intermediate file to: {}"
msgstr "" msgstr ""
#: video2x.py:85 #: video2x.py:86
msgid "" msgid ""
"Video2X CLI Version: {}\n" "Video2X CLI Version: {}\n"
"Upscaler Version: {}\n" "Upscaler Version: {}\n"
@ -249,59 +245,87 @@ msgid ""
"Contact: k4yt3x@k4yt3x.com" "Contact: k4yt3x@k4yt3x.com"
msgstr "" msgstr ""
#: video2x.py:108 #: video2x.py:109
msgid "Video2X Options" msgid "Video2X Options"
msgstr "" msgstr ""
#: video2x.py:109 #: video2x.py:110
msgid "show this help message and exit" msgid "show this help message and exit"
msgstr "" msgstr ""
#: video2x.py:110 #: video2x.py:117
msgid "source video file/directory" msgid "source video file/directory"
msgstr "" msgstr ""
#: video2x.py:111 #: video2x.py:118
msgid "output video file/directory" msgid "output video file/directory"
msgstr "" msgstr ""
#: video2x.py:112 #: video2x.py:120
msgid "video2x config file path" msgid "video2x config file path"
msgstr "" msgstr ""
#: video2x.py:114 #: video2x.py:122
msgid "log file path"
msgstr ""
#: video2x.py:124
msgid "disable logging"
msgstr ""
#: video2x.py:125
msgid "display version, lawful information and exit" msgid "display version, lawful information and exit"
msgstr "" msgstr ""
#: video2x.py:117 #: video2x.py:128
msgid "Upscaling Options" msgid "Upscaling Options"
msgstr "" msgstr ""
#: video2x.py:118 #: video2x.py:129
msgid "upscaling driver"
msgstr ""
#: video2x.py:119
msgid "scaling ratio" msgid "scaling ratio"
msgstr "" msgstr ""
#: video2x.py:120 #: video2x.py:130
msgid "output width"
msgstr ""
#: video2x.py:131
msgid "output height"
msgstr ""
#: video2x.py:132
msgid "upscaling driver"
msgstr ""
#: video2x.py:133
msgid "number of processes to use for upscaling" msgid "number of processes to use for upscaling"
msgstr "" msgstr ""
#: video2x.py:121 #: video2x.py:134
msgid "preserve extracted and upscaled frames" msgid "preserve extracted and upscaled frames"
msgstr "" msgstr ""
#: video2x.py:161 #: video2x.py:174
msgid "This file cannot be imported" msgid "This file cannot be imported"
msgstr "" msgstr ""
#: video2x.py:236 #: video2x.py:190
msgid "Specify either scaling ratio or scaling resolution, not both"
msgstr ""
#: video2x.py:194
msgid "Only one of scaling width and scaling height is specified"
msgstr ""
#: video2x.py:200
msgid "Redirecting console logs to {}"
msgstr ""
#: video2x.py:276
msgid "Program completed, taking {} seconds" msgid "Program completed, taking {} seconds"
msgstr "" msgstr ""
#: video2x.py:239 #: video2x.py:279
msgid "An exception has occurred" msgid "An exception has occurred"
msgstr "" msgstr ""

View File

@ -13,7 +13,7 @@ __ __ _ _ ___ __ __
Name: Video2X Controller Name: Video2X Controller
Creator: K4YT3X Creator: K4YT3X
Date Created: Feb 24, 2018 Date Created: Feb 24, 2018
Last Modified: June 29, 2020 Last Modified: September 9, 2020
Editor: BrianPetkovsek Editor: BrianPetkovsek
Last Modified: June 17, 2019 Last Modified: June 17, 2019
@ -81,7 +81,7 @@ language = gettext.translation(DOMAIN, LOCALE_DIRECTORY, [default_locale], fallb
language.install() language.install()
_ = language.gettext _ = language.gettext
CLI_VERSION = '4.2.0' CLI_VERSION = '4.3.0'
LEGAL_INFO = _('''Video2X CLI Version: {} LEGAL_INFO = _('''Video2X CLI Version: {}
Upscaler Version: {} Upscaler Version: {}
@ -107,7 +107,7 @@ def parse_arguments():
# video options # video options
video2x_options = parser.add_argument_group(_('Video2X Options')) video2x_options = parser.add_argument_group(_('Video2X Options'))
video2x_options.add_argument('-h', '--help', action='help', help=_('show this help message and exit')) video2x_options.add_argument('--help', action='help', help=_('show this help message and exit'))
# if help is in arguments list # if help is in arguments list
# do not require input and output path to be specified # do not require input and output path to be specified
@ -126,8 +126,10 @@ def parse_arguments():
# scaling options # scaling options
upscaling_options = parser.add_argument_group(_('Upscaling Options')) upscaling_options = parser.add_argument_group(_('Upscaling Options'))
upscaling_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_caffe') upscaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float)
upscaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float, default=2.0) upscaling_options.add_argument('-w', '--width', help=_('output width'), action='store', type=float)
upscaling_options.add_argument('-h', '--height', help=_('output height'), action='store', type=float)
upscaling_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_ncnn_vulkan')
upscaling_options.add_argument('-p', '--processes', help=_('number of processes to use for upscaling'), action='store', type=int, default=1) upscaling_options.add_argument('-p', '--processes', help=_('number of processes to use for upscaling'), action='store', type=int, default=1)
upscaling_options.add_argument('--preserve_frames', help=_('preserve extracted and upscaled frames'), action='store_true') upscaling_options.add_argument('--preserve_frames', help=_('preserve extracted and upscaled frames'), action='store_true')
@ -183,6 +185,15 @@ if video2x_args.version:
print(LEGAL_INFO) print(LEGAL_INFO)
sys.exit(0) sys.exit(0)
# additional checks on upscaling arguments
if video2x_args.ratio is not None and (video2x_args.width is not None or video2x_args.height is not None):
Avalon.error(_('Specify either scaling ratio or scaling resolution, not both'))
sys.exit(1)
if bool(video2x_args.width) ^ bool(video2x_args.height):
Avalon.error(_('Only one of scaling width and scaling height is specified'))
sys.exit(1)
# redirect output to both terminal and log file # redirect output to both terminal and log file
if video2x_args.disable_logging is False: if video2x_args.disable_logging is False:
LOGFILE = video2x_args.log LOGFILE = video2x_args.log
@ -248,6 +259,8 @@ try:
# optional parameters # optional parameters
driver=video2x_args.driver, driver=video2x_args.driver,
scale_ratio=video2x_args.ratio, scale_ratio=video2x_args.ratio,
scale_width=video2x_args.width,
scale_height=video2x_args.height,
processes=video2x_args.processes, processes=video2x_args.processes,
video2x_cache_directory=video2x_cache_directory, video2x_cache_directory=video2x_cache_directory,
extracted_frame_format=extracted_frame_format, extracted_frame_format=extracted_frame_format,

View File

@ -4,7 +4,7 @@
Creator: Video2X GUI Creator: Video2X GUI
Author: K4YT3X Author: K4YT3X
Date Created: May 5, 2020 Date Created: May 5, 2020
Last Modified: September 4, 2020 Last Modified: September 9, 2020
""" """
# local imports # local imports
@ -34,7 +34,7 @@ from PyQt5.QtGui import *
from PyQt5.QtWidgets import * from PyQt5.QtWidgets import *
import magic import magic
GUI_VERSION = '2.7.3' GUI_VERSION = '2.8.0'
LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\ LEGAL_INFO = f'''Video2X GUI Version: {GUI_VERSION}\\
Upscaler Version: {UPSCALER_VERSION}\\ Upscaler Version: {UPSCALER_VERSION}\\
@ -277,6 +277,10 @@ class Video2XMainWindow(QMainWindow):
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver) self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox') self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox')
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox') self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
self.output_width_spin_box = self.findChild(QSpinBox, 'outputWidthSpinBox')
self.output_width_spin_box.valueChanged.connect(self.mutually_exclude_scale_ratio_resolution)
self.output_height_spin_box = self.findChild(QSpinBox, 'outputHeightSpinBox')
self.output_height_spin_box.valueChanged.connect(self.mutually_exclude_scale_ratio_resolution)
self.output_file_name_format_string_line_edit = self.findChild(QLineEdit, 'outputFileNameFormatStringLineEdit') self.output_file_name_format_string_line_edit = self.findChild(QLineEdit, 'outputFileNameFormatStringLineEdit')
self.image_output_extension_line_edit = self.findChild(QLineEdit, 'imageOutputExtensionLineEdit') self.image_output_extension_line_edit = self.findChild(QLineEdit, 'imageOutputExtensionLineEdit')
self.video_output_extension_line_edit = self.findChild(QLineEdit, 'videoOutputExtensionLineEdit') self.video_output_extension_line_edit = self.findChild(QLineEdit, 'videoOutputExtensionLineEdit')
@ -310,8 +314,6 @@ class Video2XMainWindow(QMainWindow):
self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit) self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit)
self.waifu2x_caffe_path_select_button = self.findChild(QPushButton, 'waifu2xCaffePathSelectButton') self.waifu2x_caffe_path_select_button = self.findChild(QPushButton, 'waifu2xCaffePathSelectButton')
self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit)) self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit))
self.waifu2x_caffe_scale_width_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeScaleWidthSpinBox')
self.waifu2x_caffe_scale_height_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeScaleHeightSpinBox')
self.waifu2x_caffe_mode_combo_box = self.findChild(QComboBox, 'waifu2xCaffeModeComboBox') self.waifu2x_caffe_mode_combo_box = self.findChild(QComboBox, 'waifu2xCaffeModeComboBox')
self.waifu2x_caffe_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox') self.waifu2x_caffe_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox') self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox')
@ -491,8 +493,6 @@ class Video2XMainWindow(QMainWindow):
# waifu2x-caffe # waifu2x-caffe
settings = self.config['waifu2x_caffe'] settings = self.config['waifu2x_caffe']
self.waifu2x_caffe_scale_width_spin_box.setValue(settings['scale_width'])
self.waifu2x_caffe_scale_height_spin_box.setValue(settings['scale_height'])
self.waifu2x_caffe_path_line_edit.setText(str(pathlib.Path(os.path.expandvars(settings['path'])).absolute())) self.waifu2x_caffe_path_line_edit.setText(str(pathlib.Path(os.path.expandvars(settings['path'])).absolute()))
self.waifu2x_caffe_mode_combo_box.setCurrentText(settings['mode']) self.waifu2x_caffe_mode_combo_box.setCurrentText(settings['mode'])
self.waifu2x_caffe_noise_level_spin_box.setValue(settings['noise_level']) self.waifu2x_caffe_noise_level_spin_box.setValue(settings['noise_level'])
@ -605,8 +605,6 @@ class Video2XMainWindow(QMainWindow):
def resolve_driver_settings(self): def resolve_driver_settings(self):
# waifu2x-caffe # waifu2x-caffe
self.config['waifu2x_caffe']['scale_width'] = self.waifu2x_caffe_scale_width_spin_box.value()
self.config['waifu2x_caffe']['scale_height'] = self.waifu2x_caffe_scale_height_spin_box.value()
self.config['waifu2x_caffe']['path'] = os.path.expandvars(self.waifu2x_caffe_path_line_edit.text()) self.config['waifu2x_caffe']['path'] = os.path.expandvars(self.waifu2x_caffe_path_line_edit.text())
self.config['waifu2x_caffe']['mode'] = self.waifu2x_caffe_mode_combo_box.currentText() self.config['waifu2x_caffe']['mode'] = self.waifu2x_caffe_mode_combo_box.currentText()
self.config['waifu2x_caffe']['noise_level'] = self.waifu2x_caffe_noise_level_spin_box.value() self.config['waifu2x_caffe']['noise_level'] = self.waifu2x_caffe_noise_level_spin_box.value()
@ -831,6 +829,12 @@ class Video2XMainWindow(QMainWindow):
with open(config_file, 'r') as config: with open(config_file, 'r') as config:
return yaml.load(config, Loader=yaml.FullLoader) return yaml.load(config, Loader=yaml.FullLoader)
def mutually_exclude_scale_ratio_resolution(self):
if self.output_width_spin_box.value() != 0 or self.output_height_spin_box.value() != 0:
self.scale_ratio_double_spin_box.setDisabled(True)
elif self.output_width_spin_box.value() == 0 and self.output_height_spin_box.value() == 0:
self.scale_ratio_double_spin_box.setDisabled(False)
def mutually_exclude_frame_interpolation_stream_copy(self): def mutually_exclude_frame_interpolation_stream_copy(self):
if self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.value() > 0: if self.ffmpeg_migrate_streams_output_options_frame_interpolation_spin_box.value() > 0:
self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setChecked(False) self.ffmpeg_migrate_streams_output_options_copy_streams_check_box.setChecked(False)
@ -842,24 +846,6 @@ class Video2XMainWindow(QMainWindow):
def update_gui_for_driver(self): def update_gui_for_driver(self):
current_driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()] current_driver = AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]
# update scale ratio constraints
if current_driver in ['waifu2x_caffe', 'waifu2x_converter_cpp', 'anime4kcpp']:
self.scale_ratio_double_spin_box.setMinimum(0.0)
self.scale_ratio_double_spin_box.setMaximum(999.0)
self.scale_ratio_double_spin_box.setValue(2.0)
elif current_driver == 'waifu2x_ncnn_vulkan':
self.scale_ratio_double_spin_box.setMinimum(1.0)
self.scale_ratio_double_spin_box.setMaximum(2.0)
self.scale_ratio_double_spin_box.setValue(2.0)
elif current_driver == 'srmd_ncnn_vulkan':
self.scale_ratio_double_spin_box.setMinimum(2.0)
self.scale_ratio_double_spin_box.setMaximum(4.0)
self.scale_ratio_double_spin_box.setValue(2.0)
elif current_driver == 'realsr_ncnn_vulkan':
self.scale_ratio_double_spin_box.setMinimum(4.0)
self.scale_ratio_double_spin_box.setMaximum(4.0)
self.scale_ratio_double_spin_box.setValue(4.0)
# update preferred processes/threads count # update preferred processes/threads count
if current_driver == 'anime4kcpp': if current_driver == 'anime4kcpp':
self.processes_spin_box.setValue(16) self.processes_spin_box.setValue(16)
@ -1074,7 +1060,7 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
# initialize progress bar values # initialize progress bar values
upscale_begin_time = time.time() upscale_begin_time = time.time()
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path())) progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, 0, [], pathlib.Path(), pathlib.Path()))
# keep querying upscaling process and feed information to callback signal # keep querying upscaling process and feed information to callback signal
while self.upscaler.running: while self.upscaler.running:
@ -1084,6 +1070,8 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
self.upscaler.total_frames, self.upscaler.total_frames,
self.upscaler.total_processed, self.upscaler.total_processed,
self.upscaler.total_files, self.upscaler.total_files,
self.upscaler.current_pass,
self.upscaler.scaling_jobs,
self.upscaler.current_input_file, self.upscaler.current_input_file,
self.upscaler.last_frame_upscaled)) self.upscaler.last_frame_upscaled))
time.sleep(1) time.sleep(1)
@ -1098,8 +1086,10 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
total_frames = progress_information[2] total_frames = progress_information[2]
total_processed = progress_information[3] total_processed = progress_information[3]
total_files = progress_information[4] total_files = progress_information[4]
current_input_file = progress_information[5] current_pass = progress_information[5]
last_frame_upscaled = progress_information[6] scaling_jobs = progress_information[6]
current_input_file = progress_information[7]
last_frame_upscaled = progress_information[8]
# calculate fields based on frames and time elapsed # calculate fields based on frames and time elapsed
time_elapsed = time.time() - upscale_begin_time time_elapsed = time.time() - upscale_begin_time
@ -1120,7 +1110,7 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
self.overall_progress_label.setText('Overall Progress: {}/{}'.format(total_processed, total_files)) self.overall_progress_label.setText('Overall Progress: {}/{}'.format(total_processed, total_files))
self.overall_progress_bar.setMaximum(total_files) self.overall_progress_bar.setMaximum(total_files)
self.overall_progress_bar.setValue(total_processed) self.overall_progress_bar.setValue(total_processed)
self.currently_processing_label.setText('Currently Processing: {}'.format(str(current_input_file.name))) self.currently_processing_label.setText('Currently Processing: {} (pass {}/{})'.format(str(current_input_file.name), current_pass, len(scaling_jobs)))
# if show frame is checked, show preview image # if show frame is checked, show preview image
if self.frame_preview_show_preview_check_box.isChecked() and last_frame_upscaled.is_file(): if self.frame_preview_show_preview_check_box.isChecked() and last_frame_upscaled.is_file():
@ -1190,6 +1180,16 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
# load driver settings for the current driver # load driver settings for the current driver
self.driver_settings = self.config[AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]] self.driver_settings = self.config[AVAILABLE_DRIVERS[self.driver_combo_box.currentText()]]
# get scale ratio or resolution
if self.scale_ratio_double_spin_box.isEnabled():
scale_ratio = self.scale_ratio_double_spin_box.value()
scale_width = scale_height = None
else:
scale_ratio = None
scale_width = self.output_width_spin_box.value()
scale_height = self.output_height_spin_box.value()
self.upscaler = Upscaler( self.upscaler = Upscaler(
# required parameters # required parameters
input_path=input_directory, input_path=input_directory,
@ -1200,7 +1200,9 @@ It\'s also highly recommended for you to attach the [log file]({}) under the pro
# optional parameters # optional parameters
driver=AVAILABLE_DRIVERS[self.driver_combo_box.currentText()], driver=AVAILABLE_DRIVERS[self.driver_combo_box.currentText()],
scale_ratio=self.scale_ratio_double_spin_box.value(), scale_ratio=scale_ratio,
scale_width=scale_width,
scale_height=scale_height,
processes=self.processes_spin_box.value(), processes=self.processes_spin_box.value(),
video2x_cache_directory=pathlib.Path(os.path.expandvars(self.cache_line_edit.text())), video2x_cache_directory=pathlib.Path(os.path.expandvars(self.cache_line_edit.text())),
extracted_frame_format=self.config['video2x']['extracted_frame_format'].lower(), extracted_frame_format=self.config['video2x']['extracted_frame_format'].lower(),

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>756</width> <width>737</width>
<height>954</height> <height>1020</height>
</rect> </rect>
</property> </property>
<property name="acceptDrops"> <property name="acceptDrops">
@ -40,8 +40,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>744</width> <width>725</width>
<height>696</height> <height>762</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_36"> <layout class="QVBoxLayout" name="verticalLayout_36">
@ -376,6 +376,11 @@
&lt;/li&gt; &lt;/li&gt;
&lt;/ul&gt;</string> &lt;/ul&gt;</string>
</property> </property>
<item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item> <item>
<property name="text"> <property name="text">
<string>Waifu2X Caffe</string> <string>Waifu2X Caffe</string>
@ -386,11 +391,6 @@
<string>Waifu2X Converter CPP</string> <string>Waifu2X Converter CPP</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item> <item>
<property name="text"> <property name="text">
<string>SRMD NCNN Vulkan</string> <string>SRMD NCNN Vulkan</string>
@ -461,6 +461,42 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="outputWidthHorizontalLayout">
<item>
<widget class="QLabel" name="outputWidthLabel">
<property name="text">
<string>Output Width</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="outputWidthSpinBox">
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="outputHeightHorizontalLayout">
<item>
<widget class="QLabel" name="outputHeightLabel">
<property name="text">
<string>Output Height</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="outputHeightSpinBox">
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="imageOutputExtensionHorizontalLayout"> <layout class="QHBoxLayout" name="imageOutputExtensionHorizontalLayout">
<item> <item>
@ -628,48 +664,6 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<layout class="QHBoxLayout" name="waifu2xCaffeScaleWidthHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xCaffeScaleWidthLabel">
<property name="text">
<string>Scale Width</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xCaffeScaleWidthSpinBox">
<property name="toolTip">
<string>custom scale width (specifying this will overwrite scale_ratio)</string>
</property>
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xCaffeScaleHeightHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xCaffeScaleHeightLabel">
<property name="text">
<string>Scale Height</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xCaffeScaleHeightSpinBox">
<property name="toolTip">
<string>custom scale height (specifying this will overwrite scale_ratio)</string>
</property>
<property name="maximum">
<number>999999</number>
</property>
</widget>
</item>
</layout>
</item>
<item> <item>
<layout class="QHBoxLayout" name="waifu2xCaffeModeHorizontalLayout"> <layout class="QHBoxLayout" name="waifu2xCaffeModeHorizontalLayout">
<item> <item>
@ -2946,7 +2940,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>756</width> <width>737</width>
<height>21</height> <height>21</height>
</rect> </rect>
</property> </property>

View File

@ -4,7 +4,7 @@
Name: Anime4KCPP Driver Name: Anime4KCPP Driver
Author: K4YT3X Author: K4YT3X
Date Created: May 3, 2020 Date Created: May 3, 2020
Last Modified: September 1, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for Anime4KCPP. for Anime4KCPP.
@ -73,13 +73,16 @@ class WrapperMain:
return parser.parse_args(arguments) return parser.parse_args(arguments)
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
self.driver_settings['zoomFactor'] = upscaler.scale_ratio # 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 # append FFmpeg path to the end of PATH
# Anime4KCPP will then use FFmpeg to migrate audio tracks # 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
def upscale(self, input_file, output_file): def upscale(self, input_file, output_file):
"""This is the core function for WAIFU2X class """This is the core function for WAIFU2X class

View File

@ -75,6 +75,37 @@ class Ffmpeg:
return pixel_formats 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
Args:
input_file (str): input file path
video_stream_index (int): index number of the video stream
Returns:
int: number of frames in the video
"""
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
]
# turn elements into str
execute = [str(e) for e in execute]
Avalon.debug_info(f'Executing: {shlex.join(execute)}')
return int(subprocess.run(execute, check=True, stdout=subprocess.PIPE).stdout.decode().strip())
def probe_file_info(self, input_video): def probe_file_info(self, input_video):
""" Gets input video information """ Gets input video information
@ -134,6 +165,7 @@ class Ffmpeg:
# specify output file # specify output file
execute.extend([ execute.extend([
extracted_frames / f'extracted_%0d.{self.extracted_frame_format}' 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))
@ -175,6 +207,7 @@ class Ffmpeg:
execute.extend([ execute.extend([
'-i', '-i',
upscaled_frames / f'extracted_%d.{self.extracted_frame_format}' upscaled_frames / f'extracted_%d.{self.extracted_frame_format}'
# upscaled_frames / f'%06d.{self.extracted_frame_format}'
]) ])
# read FFmpeg output options # read FFmpeg output options

View File

@ -4,7 +4,7 @@
Name: RealSR NCNN Vulkan Driver Name: RealSR NCNN Vulkan Driver
Creator: K4YT3X Creator: K4YT3X
Date Created: May 26, 2020 Date Created: May 26, 2020
Last Modified: May 26, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for realsr_ncnn_vulkan. for realsr_ncnn_vulkan.
@ -44,7 +44,7 @@ class WrapperMain:
parser.add_argument('-v', action='store_true', help='verbose output') 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('-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('-o', type=str, help=argparse.SUPPRESS) # help='output image path (png) or directory')
parser.add_argument('-s', type=int, choices=[4], help='upscale ratio') parser.add_argument('-s', type=int, help='upscale ratio')
parser.add_argument('-t', type=int, help='tile size (>=32/0=auto)') 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('-m', type=str, help='realsr model path')
parser.add_argument('-g', type=int, help='gpu device to use') parser.add_argument('-g', type=int, help='gpu device to use')
@ -53,9 +53,12 @@ class WrapperMain:
return parser.parse_args(arguments) return parser.parse_args(arguments)
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
self.driver_settings['s'] = int(upscaler.scale_ratio) # self.driver_settings['s'] = int(upscaler.scale_ratio)
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
def set_scale_ratio(self, scale_ratio: int):
self.driver_settings['s'] = int(scale_ratio)
def upscale(self, input_directory, output_directory): def upscale(self, input_directory, output_directory):
"""This is the core function for RealSR NCNN Vulkan class """This is the core function for RealSR NCNN Vulkan class

View File

@ -4,7 +4,7 @@
Name: SRMD NCNN Vulkan Driver Name: SRMD NCNN Vulkan Driver
Creator: K4YT3X Creator: K4YT3X
Date Created: April 26, 2020 Date Created: April 26, 2020
Last Modified: May 11, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for srmd_ncnn_vulkan. for srmd_ncnn_vulkan.
@ -45,7 +45,7 @@ class WrapperMain:
parser.add_argument('-i', type=str, help=argparse.SUPPRESS) # help='input image path (jpg/png) or directory') 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('-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('-n', type=int, choices=range(-1, 11), help='denoise level')
parser.add_argument('-s', type=int, choices=range(2, 5), help='upscale ratio') parser.add_argument('-s', type=int, help='upscale ratio')
parser.add_argument('-t', type=int, help='tile size (>=32)') parser.add_argument('-t', type=int, help='tile size (>=32)')
parser.add_argument('-m', type=str, help='srmd model path') parser.add_argument('-m', type=str, help='srmd model path')
parser.add_argument('-g', type=int, help='gpu device to use') parser.add_argument('-g', type=int, help='gpu device to use')
@ -54,9 +54,12 @@ class WrapperMain:
return parser.parse_args(arguments) return parser.parse_args(arguments)
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
self.driver_settings['s'] = int(upscaler.scale_ratio) # self.driver_settings['s'] = int(upscaler.scale_ratio)
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
def set_scale_ratio(self, scale_ratio: int):
self.driver_settings['s'] = int(scale_ratio)
def upscale(self, input_directory, output_directory): def upscale(self, input_directory, output_directory):
"""This is the core function for SRMD ncnn Vulkan class """This is the core function for SRMD ncnn Vulkan class

View File

@ -4,7 +4,7 @@
Name: Waifu2x Caffe Driver Name: Waifu2x Caffe Driver
Author: K4YT3X Author: K4YT3X
Date Created: Feb 24, 2018 Date Created: Feb 24, 2018
Last Modified: June 7, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for waifu2x-caffe. for waifu2x-caffe.
@ -63,13 +63,16 @@ class WrapperMain:
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
# use scale width and scale height if specified # use scale width and scale height if specified
self.driver_settings['scale_ratio'] = upscaler.scale_ratio # 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 # bit_depth will be 12 at this point
# it will up updated later # it will up updated later
self.driver_settings['output_depth'] = 12 self.driver_settings['output_depth'] = 12
def set_scale_ratio(self, scale_ratio: float):
self.driver_settings['scale_ratio'] = scale_ratio
def upscale(self, input_directory, output_directory): def upscale(self, input_directory, output_directory):
""" start upscaling process """ start upscaling process
""" """

View File

@ -4,7 +4,7 @@
Name: Waifu2x Converter CPP Driver Name: Waifu2x Converter CPP Driver
Author: K4YT3X Author: K4YT3X
Date Created: February 8, 2019 Date Created: February 8, 2019
Last Modified: June 13, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for waifu2x-converter-cpp. for waifu2x-converter-cpp.
@ -67,10 +67,13 @@ class WrapperMain:
return parser.parse_args(arguments) return parser.parse_args(arguments)
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
self.driver_settings['scale-ratio'] = upscaler.scale_ratio # self.driver_settings['scale-ratio'] = upscaler.scale_ratio
self.driver_settings['jobs'] = upscaler.processes self.driver_settings['jobs'] = upscaler.processes
self.driver_settings['output-format'] = upscaler.extracted_frame_format.lower() 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
def upscale(self, input_directory, output_directory): def upscale(self, input_directory, output_directory):
""" Waifu2x Converter Driver Upscaler """ Waifu2x Converter Driver Upscaler
This method executes the upscaling of extracted frames. This method executes the upscaling of extracted frames.

View File

@ -7,7 +7,7 @@ Date Created: June 26, 2019
Last Modified: May 11, 2020 Last Modified: May 11, 2020
Editor: K4YT3X Editor: K4YT3X
Last Modified: February 22, 2020 Last Modified: September 9, 2020
Description: This class is a high-level wrapper Description: This class is a high-level wrapper
for waifu2x_ncnn_vulkan. for waifu2x_ncnn_vulkan.
@ -48,7 +48,7 @@ class WrapperMain:
parser.add_argument('-i', type=str, help=argparse.SUPPRESS) # help='input image path (jpg/png) or directory') 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('-o', type=str, help=argparse.SUPPRESS) # help='output image path (png) or directory')
parser.add_argument('-n', type=int, choices=range(-1, 4), help='denoise level') parser.add_argument('-n', type=int, choices=range(-1, 4), help='denoise level')
parser.add_argument('-s', type=int, choices=range(1, 3), help='upscale ratio') parser.add_argument('-s', type=int, help='upscale ratio')
parser.add_argument('-t', type=int, help='tile size (>=32)') parser.add_argument('-t', type=int, help='tile size (>=32)')
parser.add_argument('-m', type=str, help='waifu2x model path') parser.add_argument('-m', type=str, help='waifu2x model path')
parser.add_argument('-g', type=int, help='gpu device to use') parser.add_argument('-g', type=int, help='gpu device to use')
@ -57,11 +57,14 @@ class WrapperMain:
return parser.parse_args(arguments) return parser.parse_args(arguments)
def load_configurations(self, upscaler): def load_configurations(self, upscaler):
self.driver_settings['s'] = int(upscaler.scale_ratio) # self.driver_settings['s'] = int(upscaler.scale_ratio)
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes) self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
def set_scale_ratio(self, scale_ratio: int):
self.driver_settings['s'] = int(scale_ratio)
def upscale(self, input_directory, output_directory): def upscale(self, input_directory, output_directory):
"""This is the core function for WAIFU2X class """ This is the core function for waifu2x class
Arguments: Arguments:
input_directory {string} -- source directory path input_directory {string} -- source directory path