29 Commits

Author SHA1 Message Date
k4yt3x
5cf3271aad added Bad Apple!! to demo videos 2020-05-11 16:24:09 -04:00
k4yt3x
bcbead4d96 updated CLI usages 2020-05-11 06:57:16 -04:00
k4yt3x
a3d0465e44 updated GUI screenshot 2020-05-11 05:32:39 -04:00
k4yt3x
995fdec5c8 updated sample video URLs 2020-05-11 05:18:00 -04:00
k4yt3x
5c3ea51ccb updated demo video links 2020-05-11 05:13:06 -04:00
k4yt3x
a24b321088 updated translations 2020-05-11 04:41:05 -04:00
k4yt3x
a83249c670 fixed waifu2x-caffe pixel format check typo 2020-05-11 04:38:33 -04:00
k4yt3x
ab2f982a84 fixed waifu2x-caffe parsing error 2020-05-11 04:33:38 -04:00
k4yt3x
91401977da added frame preview, redesigned driver instance initiation and argument parsing 2020-05-11 04:17:21 -04:00
k4yt3x
99971bceb1 adjusted GUI dimensions 2020-05-10 00:59:16 -04:00
k4yt3x
0c6de8af16 re-added CLI usages 2020-05-09 23:31:34 -04:00
k4yt3x
4def30f516 added prerequisites in README 2020-05-09 23:22:36 -04:00
k4yt3x
8d553ac575 added a link for download builds 2020-05-09 23:14:24 -04:00
k4yt3x
e1a1cf578b moved badges below the icon 2020-05-09 23:13:12 -04:00
k4yt3x
4015617152 updated README for recent code updates 2020-05-09 23:12:37 -04:00
k4yt3x
648bf4fd3d added video2x banner files 2020-05-09 23:12:20 -04:00
k4yt3x
e3ed08ff40 updated logo files 2020-05-09 22:20:40 -04:00
k4yt3x
90f807655a better about and error dialog 2020-05-09 20:27:04 -04:00
k4yt3x
ab77d62c71 updated config file comments 2020-05-09 20:13:08 -04:00
k4yt3x
a64fabae87 added more GUI options for waifu2x-converter-cpp 2020-05-09 20:10:12 -04:00
k4yt3x
26558c6159 changed some wording in upscaler 2020-05-09 19:40:18 -04:00
k4yt3x
4fbbb20258 updated zh_CN translation files 2020-05-09 19:40:07 -04:00
k4yt3x
4659a9a9f5 changed gitignore to include translation files 2020-05-09 19:39:51 -04:00
k4yt3x
4c48af4fa4 output intermediate video-only file if stream migration fails 2020-05-09 19:30:24 -04:00
k4yt3x
4a6f90a1f0 fixing temp directory loading problem attempt 2 2020-05-09 05:49:59 -04:00
k4yt3x
2d9c5fe751 fixed custom cache path loading issues 2020-05-09 05:39:40 -04:00
k4yt3x
bef3861d3c fixed some spelling errors in waifu2x-caffe 2020-05-09 05:39:19 -04:00
k4yt3x
bcb54b6d2c yielding multithreading control to srmd/waifu2x-ncnn-vulkan, fixing FFmpeg framerate detection 2020-05-09 04:54:28 -04:00
k4yt3x
e82a26d44f deleted some unused imports 2020-05-09 02:23:21 -04:00
25 changed files with 1201 additions and 589 deletions

4
.gitignore vendored
View File

@@ -51,8 +51,8 @@ coverage.xml
.pytest_cache/
# Translations
*.mo
*.pot
#*.mo
#*.pot
# Django stuff:
*.log

341
README.md
View File

@@ -1,3 +1,7 @@
<p align="center">
<img src="https://user-images.githubusercontent.com/21986859/81489504-c7d1f780-9265-11ea-86c8-cc0316e2082d.png"/>
</p>
![Master Branch Version](https://img.shields.io/badge/master-v4.0.0-9cf?style=flat-square)
![GitHub release (latest by date)](https://img.shields.io/github/v/release/k4yt3x/video2x?style=flat-square)
![GitHub All Releases](https://img.shields.io/github/downloads/k4yt3x/video2x/total?style=flat-square)
@@ -5,35 +9,164 @@
![Platforms](https://img.shields.io/badge/Platforms-Windows%20%7C%20Linux%20%7C%20macOS-blue?style=flat-square)
<img alt="Become a Patron!"
src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png"
href="https://www.patreon.com/bePatron?u=34970782"
href="https://www.patreon.com/bePatron?u=34970782"
height=20 />
# Video2X Lossless Video Enlarger
<!--# Video2X Lossless Video Enlarger-->
### Official Discussion Group (Telegram): https://t.me/video2x
## Download Builds (Windows)
## [Download Builds](https://github.com/k4yt3x/video2x/releases) (Windows)
You can go to the [releases page](https://github.com/k4yt3x/video2x/releases) to download the latest builds of `Video2X`. The exe files will require no Python or Python module installation.
You can go to the [releases page](https://github.com/k4yt3x/video2x/releases) to download the latest builds of Video2X. The exe files will require no Python or Python module installation. There are two editions available.
The **`full`** package provides all packages that will possibly be needed by `Video2X`, including `FFmpeg`, `waifu2x-caffe`, `waifu2x-converter-cpp`, `waifu2x-ncnn-vulkan`, `srmd-ncnn-vulkan` and `Anime4KCPP`. The config file (`video2x.yaml`) is also already configured for the environment. All you need to do is just to launch `video2x.exe`.
- **`Full`**: full package comes pre-configured with **all** dependencies like `FFmpeg` and `waifu2x-caffe`.
- **`Light`**: ligt package comes with only Video2X binaries and a template configuration file. The user will either have to run the setup script or install and configure dependencies themselves.
The **`light`** package provides only the most basic functions of `Video2X`. Only `video2x.exe`, `video2x_setup.exe` and `video2x.yaml` are included. To setup dependencies (e.g. `FFmpeg` and `Waifu2X`) automatically, simply launch `video2x_setup.exe`.
Go to the [Quick Start](#quick-start) section for usages.
## Prerequisites
## Introduction
Component names that are **bolded** can be automatically downloaded and configured with the `video2x_setup.py` script.
Video2X is a video upscaling software based on Waifu2X, Anime4K and SRMD written in Python 3. It upscales videos and restores details from low-resolution videos. Below is a side-by-side preview.
1. Operating System: Windows / Linux
2. AMD GPU / Nvidia GPU
3. AMD GPU driver / Nvidia GPU driver / Nvidia CUDNN
4. [**FFmpeg**](https://ffmpeg.zeranoe.com/builds/)
5. One of the following drivers
- [**waifu2x-caffe**](https://github.com/lltcggie/waifu2x-caffe/releases)
- [**waifu2x-converter-cpp**](https://github.com/DeadSix27/waifu2x-converter-cpp/releases)
- [**waifu2x-ncnn-vulkan**](https://github.com/nihui/waifu2x-ncnn-vulkan)
- [**srmd-ncnn-vulkan**](https://github.com/nihui/srmd-ncnn-vulkan)
- [**Anime4KCPP**](https://github.com/TianZerL/Anime4KCPP)
![Spirited Away Demo](https://user-images.githubusercontent.com/21986859/49412428-65083280-f73a-11e8-8237-bb34158a545e.png)
*Upscale Comparison Demonstration*
**You can watch the whole demo video on YouTube: https://youtu.be/mGEfasQl2Zo**
Clip is from trailer of animated movie "千と千尋の神隠し". Copyright belongs to "株式会社スタジオジブリ (STUDIO GHIBLI INC.)". Will delete immediately if use of clip is in violation of copyright.
## Demo Videos
Below is a list of all the demo videos available.
The list is sorted from new to old.
- **Bad Apple!!**
- YouTube: https://youtu.be/-RKLdCELgkQ
- Bilibili: https://www.bilibili.com/video/BV1s5411s7xV/
- **The Pet Girl of Sakurasou 240P to 1080P 60FPS**
- Original name: さくら荘のペットな彼女
- YouTube: https://youtu.be/M0vDI1HH2_Y
- Bilibili: https://www.bilibili.com/video/BV14k4y167KP/
- **Spirited Away (360P to 4K)**
- Original name: 千と千尋の神隠し
- YouTube: https://youtu.be/mGEfasQl2Zo
- Bilibili: https://www.bilibili.com/video/BV1V5411471i/
## Screenshots
### Video2X GUI
![GUI Preview](https://user-images.githubusercontent.com/21986859/81546668-3bf5c380-936a-11ea-9583-c969ea0d862b.png)
*Video2X GUI Screenshot*
### Video2X CLI
![Video2X CLI Screenshot](https://user-images.githubusercontent.com/21986859/81039711-4fe88380-8e99-11ea-9846-175f72100a76.png)
*Video2X CLI Screenshot*
---
## Documentations
### [Video2X Wiki](https://github.com/k4yt3x/video2x/wiki)
You can find all detailed user-facing and developer-facing documentations in the [Video2X Wiki](https://github.com/k4yt3x/video2x/wiki). It covers everything from step-by-step instructions for beginners, to the code structure of this program for advanced users and developers. If this README page doesn't answer all your questions, the wiki page is where you should head to.
### [Run From Source](https://github.com/k4yt3x/video2x/wiki/Run-From-Source)
Instructions for how to run this program from source code.
### [Step-By-Step Tutorial](https://github.com/k4yt3x/video2x/wiki/Step-By-Step-Tutorial)
For those who want a detailed walk-through of how to use Video2X, you can head to the [Step-By-Step Tutorial](https://github.com/k4yt3x/video2x/wiki/Step-By-Step-Tutorial) wiki page. It includes almost every step you need to perform in order to enlarge your first video.
### [Drivers](https://github.com/k4yt3x/video2x/wiki/Drivers)
Go to the [Drivers](https://github.com/k4yt3x/video2x/wiki/Drivers) wiki page if you want to see a detailed description on the different types of drivers implemented by Video2X. This wiki page contains detailed difference between different drivers, and how to download and set each of them up for Video2X.
### [Q&A](https://github.com/k4yt3x/video2x/wiki/Q&A)
If you have any questions, first try visiting our [Q&A](https://github.com/k4yt3x/video2x/wiki/Q&A) page to see if your question is answered there. If not, open an issue and we will respond to your questions ASAP. Alternatively, you can also join our [Telegram discussion group](https://t.me/video2x) and ask your questions there.
---
### Sample Videos
If you can't find a video clip to begin with, or if you want to see a before-after comparison, we have prepared some sample clips for you. The quick start guide down below will also be based on the name of the sample clips.
![sample_video](https://user-images.githubusercontent.com/21986859/52905766-d5512b00-3236-11e9-9aea-077636539679.png)
*Sample Upscale Videos*
- [Sample Video (240P) 4.54MB](https://files.k4yt3x.com/Resources/Videos/sample_input.mp4)
- [Sample Video Upscaled (1080P) 4.54MB](https://files.k4yt3x.com/Resources/Videos/sample_output.mp4)
- [Sample Video Original (1080P) 22.2MB](https://files.k4yt3x.com/Resources/Videos/sample_original.mp4)
Clip is from anime "さくら荘のペットな彼女". Copyright belongs to "株式会社アニプレックス (Aniplex Inc.)". Will delete immediately if use of clip is in violation of copyright.
---
## Quick Start
### Prerequisites
Before running Video2X, you'll need to ensure you have installed the drivers' external dependencies such as GPU drivers.
- waifu2x-caffe
- GPU mode: Nvidia graphics card driver
- cuDNN mode: Nvidia CUDA and [cuDNN](https://docs.nvidia.com/deeplearning/sdk/cudnn-install/index.html#install-windows)
- Other Drivers
- GPU driver if you want to use GPU for processing
### Running Video2X (GUI)
The easiest way to run Video2X is to use the full build. Extract the full release zip file and you'll get these files.
![Video2X Release Files](https://user-images.githubusercontent.com/21986859/81489846-28633380-926a-11ea-9e81-fb92f492e14c.png)
Simply double click on video2x_gui.exe to launch the GUI.
![Video2X GUI Main Tab](https://user-images.githubusercontent.com/21986859/81489858-4c267980-926a-11ea-9ab2-38ec738f2fb6.png)
Then, drag the videos you wish to upscale into the window and select the appropriate output path.
![drag-drop](https://user-images.githubusercontent.com/21986859/81489880-7bd58180-926a-11ea-85ae-b72d2f4f5e72.png)
Tweak the settings if you want to, then hit the start button at the bottom and the upscale will start. Now you'll just have to wait for it to complete.
![upscale-started](https://user-images.githubusercontent.com/21986859/81489924-ce16a280-926a-11ea-831c-6c66b950f957.png)
### Running Video2X (CLI)
#### Basic Upscale Example
This example command below uses `waifu2x-caffe` to enlarge the video `sample-input.mp4` two double its original size.
```shell
python video2x.py -i sample-input.mp4 -o sample-output.mp4 -r 2 -d waifu2x_caffe
```
#### Advanced Upscale Example
If you would like to tweak engine-specific settings, either specify the corresponding argument after `--`, or edit the corresponding field in the configuration file `video2x.yaml`. **Command line arguments will overwrite default values in the config file.**
This example below adds enables TTA for `waifu2x-caffe`.
```shell
python video2x.py -i sample-input.mp4 -o sample-output.mp4 -r 2 -d waifu2x_caffe -- --tta 1
```
To see a help page for driver-specific settings, use `-d` to select the driver and append `-- --help` as demonstrated below. This will print all driver-specific settings and descriptions.
```shell
python video2x.py -d waifu2x_caffe -- --help
```
---
## Recent Changes
@@ -62,148 +195,11 @@ Component names that are **bolded** can be automatically downloaded and configur
- Added support for Anime4KCPP
## Description
Video2X is an automation software based on waifu2x image enlarging engine. It extracts frames from a video, enlarge it by a number of times without losing any details or quality, keeping lines smooth and edges sharp.
For short: **Video2X enlarges your video without losing details**.
Watch for the sharper edges in this screenshot around the shadows:
![preview](https://user-images.githubusercontent.com/21986859/49412428-65083280-f73a-11e8-8237-bb34158a545e.png)
*Upscale Comparison Demonstration*
**You can also watch the YouTube video Demo: https://www.youtube.com/watch?v=PG94iPoeoZk**
Clip is from trailer of animated movie "千と千尋の神隠し". Copyright belongs to "株式会社スタジオジブリ (STUDIO GHIBLI INC.)". Will delete immediately if use of clip is in violation of copyright.
## Screenshots
### Video2X GUI
![Video2X GUI Main Tab Screenshot](https://user-images.githubusercontent.com/21986859/81241806-dcf71e00-8ffa-11ea-88ed-50b062d9bb5e.png)
*Video2X GUI Main Tab Screenshot*
![Video2X GUI Driver Settings Screenshot](https://user-images.githubusercontent.com/21986859/81241837-f9935600-8ffa-11ea-8b89-5ae098b63de4.png)
*Video2X GUI Driver Settings Screenshot*
### Video2X CLI
![Video2X CLI Screenshot](https://user-images.githubusercontent.com/21986859/81039711-4fe88380-8e99-11ea-9846-175f72100a76.png)
*Video2X CLI Screenshot*
---
## Documentations
### [Video2X Wiki](https://github.com/k4yt3x/video2x/wiki)
You can find all detailed user-facing and developer-facing documentations in the [Video2X Wiki](https://github.com/k4yt3x/video2x/wiki). It covers everything from step-by-step instructions for beginners, to the code structure of this program for advanced users and developers. If this README page doesn't answer all your questions, the wiki page is where you should head to.
### [Step-By-Step Tutorial](https://github.com/k4yt3x/video2x/wiki/Step-By-Step-Tutorial)
For those who want a detailed walk-through of how to use `Video2X`, you can head to the [Step-By-Step Tutorial](https://github.com/k4yt3x/video2x/wiki/Step-By-Step-Tutorial) wiki page. It includes almost every step you need to perform in order to enlarge your first video.
### [Drivers](https://github.com/k4yt3x/video2x/wiki/Drivers)
Go to the [Drivers](https://github.com/k4yt3x/video2x/wiki/Drivers) wiki page if you want to see a detailed description on the different types of drivers implemented by `Video2X`. This wiki page contains detailed difference between different drivers, and how to download and set each of them up for `Video2X`.
### [Q&A](https://github.com/k4yt3x/video2x/wiki/Q&A)
If you have any questions, first try visiting our [Q&A](https://github.com/k4yt3x/video2x/wiki/Q&A) page to see if your question is answered there. If not, open an issue and we will respond to your questions ASAP.
---
## Quick Start
### Prerequisites
- **Python 3.8**
Download: https://www.python.org/downloads/windows/
- **FFmpeg Windows Build**
Download: https://ffmpeg.org/download.html
- **waifu2x-caffe** (designed for Nvidia CUDA/cuDNN)
Download: https://github.com/lltcggie/waifu2x-caffe/releases
- **waifu2x-converter-cpp**
Download: https://github.com/DeadSix27/waifu2x-converter-cpp/releases
- **waifu2x-ncnn-vulkan**
Download: https://github.com/nihui/waifu2x-ncnn-vulkan/releases
- **Anime4KCPP**
Download: https://github.com/TianZerL/Anime4KCPP/releases
- **srmd-ncnn-vulkan**
Download: https://github.com/nihui/srmd-ncnn-vulkan/releases
### Installing Dependencies
First, clone the video2x repository.
```shell
git clone https://github.com/k4yt3x/video2x.git
cd video2x/src
```
Then you may run the `video2x_setup.py` script to install and configure the dependencies automatically. This script is designed and tested on Windows 10.
This script will install the newest version of `ffmpeg`, and all upscaling drivers to `%LOCALAPPDATA%\\video2x` and all required python libraries.
```shell
python video2x_setup.py
```
Alternatively, you can also install the dependencies manually. Please refer to the prerequisites section to see what's needed.
Then you'll need to install python dependencies before start using video2x. Install simply by executing the following command.
```shell
pip install -r requirements.txt
```
### Sample Videos
If you can't find a video clip to begin with, or if you want to see a before-after comparison, we have prepared some sample clips for you. The quick start guide down below will also be based on the name of the sample clips.
![sample_video](https://user-images.githubusercontent.com/21986859/52905766-d5512b00-3236-11e9-9aea-077636539679.png)
*Sample Upscale Videos*
- [Sample Video Original (240P) 1.7MB](https://files.k4yt3x.com/Resources/Videos/sample_input.mp4)
- [Sample Video Upscaled (1080P) 4.8MB](https://files.k4yt3x.com/Resources/Videos/sample_output.mp4)
Clip is from anime "さくら荘のペットな彼女". Copyright belongs to "株式会社アニプレックス (Aniplex Inc.)". Will delete immediately if use of clip is in violation of copyright.
### Basic Upscale Example
This example command below uses `waifu2x-caffe` to enlarge the video `sample-input.mp4` two double its original size.
```shell
python video2x.py -i sample-input.mp4 -o sample-output.mp4 -r 2 -d waifu2x_caffe
```
### Advanced Upscale Example
If you would like to tweak engine-specific settings, either specify the corresponding argument after `--`, or edit the corresponding field in the configuration file `video2x.yaml`. **Command line arguments will overwrite default values in the config file.**
This example below adds enables TTA for `waifu2x-caffe`.
```shell
python video2x.py -i sample-input.mp4 -o sample-output.mp4 -r 2 -d waifu2x_caffe -- --tta 1
```
To see a help page for driver-specific settings, use `-d` to select the driver and append `-- --help` as demonstrated below. This will print all driver-specific settings and descriptions.
```shell
python video2x.py -d waifu2x_caffe -- --help
```
---
# Full Usage
## General Options:
## Video2X Options
### -h, --help
show this help message and exit
@@ -217,25 +213,30 @@ python video2x.py -d waifu2x_caffe -- --help
### -c CONFIG, --config CONFIG
video2x config file path
### -d {waifu2x_caffe,waifu2x_converter_cpp,waifu2x_ncnn_vulkan,srmd_ncnn_vulkan,anime4kcpp}, --driver {waifu2x_caffe,waifu2x_converter_cpp,waifu2x_ncnn_vulkan,srmd_ncnn_vulkan,anime4kcpp}
### -v, --version
display version, lawful information and exit
## Upscaling Options
### -d DRIVER, --driver DRIVER
upscaling driver (default: waifu2x_caffe)
Available options are:
- waifu2x_caffe
- waifu2x_converter_cpp
- waifu2x_ncnn_vulkan
- srmd_ncnn_vulkan
- anime4kcpp
### -r RATIO, --ratio RATIO
scaling ratio
### -p PROCESSES, --processes PROCESSES
number of processes to use for upscaling (default: 1)
### -v, --version
display version, lawful information and exit
## Scaling Options
### --width WIDTH
output video width
### --height HEIGHT
output video height
### -r RATIO, --ratio RATIO
scaling ratio
### --preserve_frames
preserve extracted and upscaled frames (default: False)
---

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

BIN
src/images/Video2X Logo.psd Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -5,8 +5,8 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: 2020-05-08 22:10-0400\n"
"PO-Revision-Date: 2020-05-08 22:11-0400\n"
"POT-Creation-Date: 2020-05-11 04:39-0400\n"
"PO-Revision-Date: 2020-05-11 04:40-0400\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: zh_CN\n"
@@ -14,174 +14,190 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
"X-Generator: Poedit 2.3\n"
"X-Generator: Poedit 2.3.1\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: progress_monitor.py:42
msgid "Upscaling Progress"
msgstr "放大进度"
#: upscaler.py:105
#: upscaler.py:104
msgid "Specified or default cache directory is a file/link"
msgstr "指定或默认的缓存目录是文件/链接"
#: upscaler.py:111
#: upscaler.py:110
msgid "Creating cache directory {}"
msgstr "创建缓存目录 {}"
#: upscaler.py:114
#: upscaler.py:113
msgid "Unable to create {}"
msgstr "无法创建 {}"
#: upscaler.py:119
#: upscaler.py:118
msgid "Extracted frames are being saved to: {}"
msgstr "提取的帧将被保存到:{}"
#: upscaler.py:121
#: upscaler.py:120
msgid "Upscaled frames are being saved to: {}"
msgstr "已放大的帧将被保存到:{}"
#: upscaler.py:131
#: upscaler.py:130
msgid "Cleaning up cache directory: {}"
msgstr "清理缓存目录:{}"
#: upscaler.py:134
#: upscaler.py:133
msgid "Unable to delete: {}"
msgstr "无法删除:{}"
#: upscaler.py:140 upscaler.py:155 upscaler.py:166
#: upscaler.py:139 upscaler.py:154 upscaler.py:165
msgid "Input and output path type mismatch"
msgstr "输入和输出路径类型不匹配"
#: upscaler.py:141
#: upscaler.py:140
msgid "Input is multiple files but output is not directory"
msgstr "输入是多个文件,但输出不是目录"
#: upscaler.py:145
#: upscaler.py:144
msgid "Input path {} is neither a file nor a directory"
msgstr "输入路径 {} 既不是文件也不是目录"
#: upscaler.py:149 upscaler.py:171
#: upscaler.py:148 upscaler.py:170
msgid "Input directory and output directory cannot be the same"
msgstr "输入目录和输出目录不能相同"
#: upscaler.py:156
#: upscaler.py:155
msgid "Input is single file but output is directory"
msgstr "所选的输入路径是单个文件,但输出路径是目录"
#: upscaler.py:159
#: upscaler.py:158
msgid "No suffix found in output file path"
msgstr "在输出文件路径中未找到后缀"
#: upscaler.py:160
#: upscaler.py:159
msgid "Suffix must be specified for FFmpeg"
msgstr "必须为 FFmpeg 指定后缀"
#: upscaler.py:167
#: upscaler.py:166
msgid "Input is directory but output is existing single file"
msgstr "输入是目录,但输出是现有的单个文件"
#: upscaler.py:176
#: upscaler.py:175
msgid "Input path is neither a file nor a directory"
msgstr "输入路径既不是文件也不是目录"
#: upscaler.py:185
#: upscaler.py:184
msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr "在指定的路径下找不到 FFmpeg 或 FFprobe"
#: upscaler.py:186 upscaler.py:196
#: upscaler.py:185 upscaler.py:195
msgid "Please check the configuration file settings"
msgstr "请检查配置文件设置"
#: upscaler.py:195
#: upscaler.py:194
msgid "Specified driver executable directory doesn't exist"
msgstr "指定驱动的可执行文件不存在"
#: upscaler.py:222
#: upscaler.py:221
msgid "Failed to parse driver argument: {}"
msgstr "解析驱动程序参数失败:{}"
#: upscaler.py:237
#: upscaler.py:253
msgid "Unrecognized driver: {}"
msgstr "无法识别的驱动名称:{}"
#: upscaler.py:309
#: upscaler.py:293
msgid "Starting progress monitor"
msgstr "启动进度监视器"
#: upscaler.py:314
#: upscaler.py:298
msgid "Starting upscaled image cleaner"
msgstr "启动已放大图像清理程序"
#: upscaler.py:323 upscaler.py:340
#: upscaler.py:307 upscaler.py:324
msgid "Killing progress monitor"
msgstr "终结进度监视器"
#: upscaler.py:326 upscaler.py:343
#: upscaler.py:310 upscaler.py:327
msgid "Killing upscaled image cleaner"
msgstr "终结已放大图像清理程序"
#: upscaler.py:347
#: upscaler.py:331
msgid "Terminating all processes"
msgstr "正在终止所有进程"
#: upscaler.py:354
#: upscaler.py:338
msgid "Main process waiting for subprocesses to exit"
msgstr "主进程开始等待子进程结束"
#: upscaler.py:373 upscaler.py:377
#: upscaler.py:357 upscaler.py:361
msgid "Subprocess {} exited with code {}"
msgstr "子进程 {} 结束,返回码 {}"
#: upscaler.py:383
#: upscaler.py:367
msgid "Stop signal received"
msgstr "收到停止信号"
#: upscaler.py:388
#: upscaler.py:372
msgid "Subprocess execution ran into an error"
msgstr "子进程执行遇到错误"
#: upscaler.py:430
#: upscaler.py:421
msgid "Upscaling single video file: {}"
msgstr "放大单个视频文件:{}"
#: upscaler.py:452 upscaler.py:515
#: upscaler.py:443 upscaler.py:502
msgid "Starting to upscale extracted images"
msgstr "开始对提取的帧进行放大"
#: upscaler.py:461 upscaler.py:517
#: upscaler.py:448 upscaler.py:504
msgid "Upscaling completed"
msgstr "放大完成"
#: upscaler.py:470
#: upscaler.py:457
msgid "Reading video information"
msgstr "读取视频信息"
#: upscaler.py:484
#: upscaler.py:471
msgid "Aborting: No video stream found"
msgstr "程序中止:文件中未找到视频流"
#: upscaler.py:502
#: upscaler.py:490
msgid "Unsupported pixel format: {}"
msgstr "不支持的像素格式:{}"
#: upscaler.py:505
#: upscaler.py:493
msgid "Framerate: {}"
msgstr "帧率:{}"
#: upscaler.py:520
#: upscaler.py:507
msgid "Converting extracted frames into video"
msgstr "将提取的帧转换为视频"
msgstr "正在将提取的帧转换为视频"
#: upscaler.py:525
#: upscaler.py:514
msgid "Conversion completed"
msgstr "转换已完成"
#: upscaler.py:528
msgid "Migrating audio tracks and subtitles to upscaled video"
msgstr "将音轨和字幕迁移到放大后的视频"
#: upscaler.py:518
msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr "正在将音频、字幕和其他流迁移到放大后的视频"
#: video2x.py:87
#: upscaler.py:527
msgid "Failed to migrate streams"
msgstr "迁移流失败"
#: upscaler.py:528
msgid "Trying to output video without additional streams"
msgstr "正在尝试输出不含其他流的视频"
#: upscaler.py:535
msgid "Output video file exists, aborting"
msgstr "输出目标文件已存在,取消输出"
#: upscaler.py:539
msgid "Writing intermediate file to: {}"
msgstr "正在将中间视频文件写入至:{}"
#: video2x.py:84
msgid ""
"Video2X Version: {}\n"
"Author: K4YT3X\n"
@@ -195,66 +211,68 @@ msgstr ""
"GitHub 主页https://github.com/k4yt3x/video2x\n"
"联系方式k4yt3x@k4yt3x.com"
#: video2x.py:109
msgid "General Options"
msgstr "通用选项"
#: video2x.py:106
msgid "Video2X Options"
msgstr "Video2X 选项"
#: video2x.py:110
#: video2x.py:107
msgid "show this help message and exit"
msgstr "显示此帮助消息并退出"
#: video2x.py:111
#: video2x.py:108
msgid "source video file/directory"
msgstr "源视频文件/目录"
#: video2x.py:112
#: video2x.py:109
msgid "output video file/directory"
msgstr "输出视频文件/目录"
#: video2x.py:113
#: video2x.py:110
msgid "video2x config file path"
msgstr "video2x 配置文件路径"
#: video2x.py:115
msgid "upscaling driver"
msgstr "视频放大驱动"
#: video2x.py:116
msgid "number of processes to use for upscaling"
msgstr "并发进程数"
#: video2x.py:117
#: video2x.py:112
msgid "display version, lawful information and exit"
msgstr "显示版本和法律信息并退出"
#: video2x.py:120
msgid "Scaling Options"
msgstr "缩放选项"
#: video2x.py:115
msgid "Upscaling Options"
msgstr "视频放大选项"
#: video2x.py:121
msgid "output video width"
msgstr "输出视频宽度"
#: video2x.py:116
msgid "upscaling driver"
msgstr "视频放大驱动"
#: video2x.py:122
msgid "output video height"
msgstr "输出视频高度"
#: video2x.py:123
#: video2x.py:117
msgid "scaling ratio"
msgstr "缩放比"
#: video2x.py:163
#: video2x.py:118
msgid "number of processes to use for upscaling"
msgstr "并发进程数"
#: video2x.py:119
msgid "preserve extracted and upscaled frames"
msgstr "保留提取的和放大的帧"
#: video2x.py:159
msgid "This file cannot be imported"
msgstr "此文件无法被当作模块导入"
#: video2x.py:224
#: video2x.py:229
msgid "Program completed, taking {} seconds"
msgstr "程序执行完毕,总计花费 {} 秒"
#: video2x.py:227
#: video2x.py:232
msgid "An exception has occurred"
msgstr "发生了异常"
#~ msgid "output video width"
#~ msgstr "输出视频宽度"
#~ msgid "output video height"
#~ msgstr "输出视频高度"
#~ msgid "You must specify input video file/directory path"
#~ msgstr "您必须指定输入视频文件/目录路径"

View File

@@ -4,7 +4,7 @@
Name: Video2X Upscale Progress Monitor
Author: BrianPetkovsek
Date Created: May 7, 2020
Last Modified: May 7, 2020
Last Modified: May 10, 2020
"""
# built-in imports
@@ -47,7 +47,10 @@ class ProgressMonitor(threading.Thread):
while self.running:
with contextlib.suppress(FileNotFoundError):
self.upscaler.total_frames_upscaled = len([f for f in self.upscaler.upscaled_frames.iterdir() if str(f).lower().endswith(self.upscaler.image_format.lower())])
upscaled_frames = [f for f in self.upscaler.upscaled_frames.iterdir() if str(f).lower().endswith(self.upscaler.image_format.lower())]
if len(upscaled_frames) >= 1:
self.upscaler.last_frame_upscaled = sorted(upscaled_frames)[-1]
self.upscaler.total_frames_upscaled = len(upscaled_frames)
# update progress bar
delta = self.upscaler.total_frames_upscaled - previous_cycle_frames

View File

@@ -4,7 +4,7 @@
Name: Video2X Upscaler
Author: K4YT3X
Date Created: December 10, 2018
Last Modified: May 8, 2020
Last Modified: May 10, 2020
Description: This file contains the Upscaler class. Each
instance of the Upscaler class is an upscaler on an image or
@@ -76,8 +76,6 @@ class Upscaler:
# optional arguments
self.driver = 'waifu2x_caffe'
self.scale_width = None
self.scale_height = None
self.scale_ratio = None
self.processes = 1
self.video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
@@ -91,6 +89,7 @@ class Upscaler:
self.total_videos = 0
self.total_processed = 0
self.current_input_video = pathlib.Path()
self.last_frame_upscaled = pathlib.Path()
def create_temp_directories(self):
"""create temporary directories
@@ -176,7 +175,7 @@ class Upscaler:
Avalon.error(_('Input path is neither a file nor a directory'))
raise FileNotFoundError(f'{self.input} is neither file nor directory')
# check Fmpeg settings
# check FFmpeg settings
ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
if not ((pathlib.Path(ffmpeg_path / 'ffmpeg.exe').is_file() and
pathlib.Path(ffmpeg_path / 'ffprobe.exe').is_file()) or
@@ -222,6 +221,23 @@ class Upscaler:
Avalon.error(_('Failed to parse driver argument: {}').format(e.args[0]))
raise e
# waifu2x-caffe scale_ratio, scale_width and scale_height check
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
@@ -257,7 +273,7 @@ class Upscaler:
process_directory.mkdir(parents=True, exist_ok=True)
# waifu2x-converter-cpp will perform multi-threading within its own process
if self.driver == 'waifu2x_converter_cpp':
if self.driver in ['waifu2x_converter_cpp', 'waifu2x_ncnn_vulkan', 'srmd_ncnn_vulkan']:
process_directories = [self.extracted_frames]
else:
@@ -269,41 +285,9 @@ class Upscaler:
# rotate list
process_directories = process_directories[-1:] + process_directories[:-1]
# create threads and start them
# create driver processes and start them
for process_directory in process_directories:
DriverWrapperMain = getattr(importlib.import_module(f'wrappers.{self.driver}'), 'WrapperMain')
driver = DriverWrapperMain(copy.deepcopy(self.driver_settings))
# if the driver being used is waifu2x-caffe
if self.driver == 'waifu2x_caffe':
self.process_pool.append(driver.upscale(process_directory,
self.upscaled_frames,
self.scale_ratio,
self.scale_width,
self.scale_height,
self.image_format,
self.bit_depth))
# if the driver being used is waifu2x-converter-cpp
elif self.driver == 'waifu2x_converter_cpp':
self.process_pool.append(driver.upscale(process_directory,
self.upscaled_frames,
self.scale_ratio,
self.processes,
self.image_format))
# if the driver being used is waifu2x-ncnn-vulkan
elif self.driver == 'waifu2x_ncnn_vulkan':
self.process_pool.append(driver.upscale(process_directory,
self.upscaled_frames,
self.scale_ratio))
# if the driver being used is srmd_ncnn_vulkan
elif self.driver == 'srmd_ncnn_vulkan':
self.process_pool.append(driver.upscale(process_directory,
self.upscaled_frames,
self.scale_ratio))
self.process_pool.append(self.driver_object.upscale(process_directory, self.upscaled_frames))
# start progress bar in a different thread
Avalon.debug_info(_('Starting progress monitor'))
@@ -402,6 +386,13 @@ class Upscaler:
# define process pool to contain processes
self.process_pool = []
# load driver modules
DriverWrapperMain = getattr(importlib.import_module(f'wrappers.{self.driver}'), 'WrapperMain')
self.driver_object = DriverWrapperMain(self.driver_settings)
# load options from upscaler class into driver settings
self.driver_object.load_configurations(self)
# parse arguments for waifu2x
# check argument sanity
self._check_arguments()
@@ -451,12 +442,8 @@ class Upscaler:
os.environ['PATH'] += f';{self.ffmpeg_settings["ffmpeg_path"]}'
Avalon.info(_('Starting to upscale extracted images'))
# import and initialize Anime4KCPP wrapper
DriverWrapperMain = getattr(importlib.import_module('wrappers.anime4kcpp'), 'WrapperMain')
driver = DriverWrapperMain(copy.deepcopy(self.driver_settings))
# run Anime4KCPP
self.process_pool.append(driver.upscale(self.current_input_video, output_video, self.scale_ratio, self.processes))
self.process_pool.append(self.driver_object.upscale(self.current_input_video, output_video))
self._wait()
Avalon.info(_('Upscaling completed'))
@@ -489,27 +476,27 @@ class Upscaler:
self._wait()
# get average frame rate of video stream
framerate = float(Fraction(video_info['streams'][video_stream_index]['avg_frame_rate']))
framerate = float(Fraction(video_info['streams'][video_stream_index]['r_frame_rate']))
fm.pixel_format = video_info['streams'][video_stream_index]['pix_fmt']
# get a dict of all pixel formats and corresponding bit depth
pixel_formats = fm.get_pixel_formats()
if self.driver == 'waifu2x_caffe':
# get a dict of all pixel formats and corresponding bit depth
pixel_formats = fm.get_pixel_formats()
# try getting pixel format's corresponding bti depth
try:
self.bit_depth = pixel_formats[fm.pixel_format]
except KeyError:
Avalon.error(_('Unsupported pixel format: {}').format(fm.pixel_format))
raise UnsupportedPixelError(f'unsupported pixel format {fm.pixel_format}')
# try getting pixel format's corresponding bti depth
try:
self.driver_settings['output_depth'] = pixel_formats[fm.pixel_format]
except KeyError:
Avalon.error(_('Unsupported pixel format: {}').format(fm.pixel_format))
raise UnsupportedPixelError(f'unsupported pixel format {fm.pixel_format}')
Avalon.info(_('Framerate: {}').format(framerate))
# width/height will be coded width/height x upscale factor
if self.scale_ratio:
original_width = video_info['streams'][video_stream_index]['width']
original_height = video_info['streams'][video_stream_index]['height']
self.scale_width = int(self.scale_ratio * original_width)
self.scale_height = int(self.scale_ratio * original_height)
original_width = video_info['streams'][video_stream_index]['width']
original_height = video_info['streams'][video_stream_index]['height']
scale_width = int(self.scale_ratio * original_width)
scale_height = int(self.scale_ratio * original_height)
# upscale images one by one using waifu2x
Avalon.info(_('Starting to upscale extracted images'))
@@ -520,14 +507,37 @@ class Upscaler:
Avalon.info(_('Converting extracted frames into video'))
# use user defined output size
self.process_pool.append(fm.convert_video(framerate, f'{self.scale_width}x{self.scale_height}', self.upscaled_frames))
self.process_pool.append(fm.assemble_video(framerate,
f'{scale_width}x{scale_height}',
self.upscaled_frames))
self._wait()
Avalon.info(_('Conversion completed'))
# migrate audio tracks and subtitles
Avalon.info(_('Migrating audio tracks and subtitles to upscaled video'))
self.process_pool.append(fm.migrate_audio_tracks_subtitles(self.current_input_video, output_video, self.upscaled_frames))
self._wait()
try:
# migrate audio tracks and subtitles
Avalon.info(_('Migrating audio, subtitles and other streams to upscaled video'))
self.process_pool.append(fm.migrate_streams(self.current_input_video,
output_video,
self.upscaled_frames))
self._wait()
# if failed to copy streams
# use file with only video stream
except subprocess.CalledProcessError:
Avalon.error(_('Failed to migrate streams'))
Avalon.warning(_('Trying to output video without additional streams'))
# construct output file path
output_video_path = output_video.parent / f'{output_video.stem}{fm.intermediate_file_name.suffix}'
# if output file already exists, cancel
if output_video_path.exists():
Avalon.error(_('Output video file exists, aborting'))
# otherwise, rename intermediate file to the output file
else:
Avalon.info(_('Writing intermediate file to: {}').format(output_video_path.absolute()))
(self.upscaled_frames / fm.intermediate_file_name).rename(output_video_path)
# destroy temp directories
self.cleanup_temp_directories()
@@ -535,6 +545,7 @@ class Upscaler:
except (Exception, KeyboardInterrupt, SystemExit) as e:
with contextlib.suppress(ValueError):
self.cleanup_temp_directories()
self.running = False
raise e
# increment total number of videos processed

262
src/video2x.pot Normal file
View File

@@ -0,0 +1,262 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR ORGANIZATION
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2020-05-11 04:39-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=cp1252\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: pygettext.py 1.5\n"
#: progress_monitor.py:42
msgid "Upscaling Progress"
msgstr ""
#: upscaler.py:104
msgid "Specified or default cache directory is a file/link"
msgstr ""
#: upscaler.py:110
msgid "Creating cache directory {}"
msgstr ""
#: upscaler.py:113
msgid "Unable to create {}"
msgstr ""
#: upscaler.py:118
msgid "Extracted frames are being saved to: {}"
msgstr ""
#: upscaler.py:120
msgid "Upscaled frames are being saved to: {}"
msgstr ""
#: upscaler.py:130
msgid "Cleaning up cache directory: {}"
msgstr ""
#: upscaler.py:133
msgid "Unable to delete: {}"
msgstr ""
#: upscaler.py:139 upscaler.py:154 upscaler.py:165
msgid "Input and output path type mismatch"
msgstr ""
#: upscaler.py:140
msgid "Input is multiple files but output is not directory"
msgstr ""
#: upscaler.py:144
msgid "Input path {} is neither a file nor a directory"
msgstr ""
#: upscaler.py:148 upscaler.py:170
msgid "Input directory and output directory cannot be the same"
msgstr ""
#: upscaler.py:155
msgid "Input is single file but output is directory"
msgstr ""
#: upscaler.py:158
msgid "No suffix found in output file path"
msgstr ""
#: upscaler.py:159
msgid "Suffix must be specified for FFmpeg"
msgstr ""
#: upscaler.py:166
msgid "Input is directory but output is existing single file"
msgstr ""
#: upscaler.py:175
msgid "Input path is neither a file nor a directory"
msgstr ""
#: upscaler.py:184
msgid "FFmpeg or FFprobe cannot be found under the specified path"
msgstr ""
#: upscaler.py:185 upscaler.py:195
msgid "Please check the configuration file settings"
msgstr ""
#: upscaler.py:194
msgid "Specified driver executable directory doesn't exist"
msgstr ""
#: upscaler.py:221
msgid "Failed to parse driver argument: {}"
msgstr ""
#: upscaler.py:253
msgid "Unrecognized driver: {}"
msgstr ""
#: upscaler.py:293
msgid "Starting progress monitor"
msgstr ""
#: upscaler.py:298
msgid "Starting upscaled image cleaner"
msgstr ""
#: upscaler.py:307 upscaler.py:324
msgid "Killing progress monitor"
msgstr ""
#: upscaler.py:310 upscaler.py:327
msgid "Killing upscaled image cleaner"
msgstr ""
#: upscaler.py:331
msgid "Terminating all processes"
msgstr ""
#: upscaler.py:338
msgid "Main process waiting for subprocesses to exit"
msgstr ""
#: upscaler.py:357 upscaler.py:361
msgid "Subprocess {} exited with code {}"
msgstr ""
#: upscaler.py:367
msgid "Stop signal received"
msgstr ""
#: upscaler.py:372
msgid "Subprocess execution ran into an error"
msgstr ""
#: upscaler.py:421
msgid "Upscaling single video file: {}"
msgstr ""
#: upscaler.py:443 upscaler.py:502
msgid "Starting to upscale extracted images"
msgstr ""
#: upscaler.py:448 upscaler.py:504
msgid "Upscaling completed"
msgstr ""
#: upscaler.py:457
msgid "Reading video information"
msgstr ""
#: upscaler.py:471
msgid "Aborting: No video stream found"
msgstr ""
#: upscaler.py:490
msgid "Unsupported pixel format: {}"
msgstr ""
#: upscaler.py:493
msgid "Framerate: {}"
msgstr ""
#: upscaler.py:507
msgid "Converting extracted frames into video"
msgstr ""
#: upscaler.py:514
msgid "Conversion completed"
msgstr ""
#: upscaler.py:518
msgid "Migrating audio, subtitles and other streams to upscaled video"
msgstr ""
#: upscaler.py:527
msgid "Failed to migrate streams"
msgstr ""
#: upscaler.py:528
msgid "Trying to output video without additional streams"
msgstr ""
#: upscaler.py:535
msgid "Output video file exists, aborting"
msgstr ""
#: upscaler.py:539
msgid "Writing intermediate file to: {}"
msgstr ""
#: video2x.py:84
msgid ""
"Video2X Version: {}\n"
"Author: K4YT3X\n"
"License: GNU GPL v3\n"
"Github Page: https://github.com/k4yt3x/video2x\n"
"Contact: k4yt3x@k4yt3x.com"
msgstr ""
#: video2x.py:106
msgid "Video2X Options"
msgstr ""
#: video2x.py:107
msgid "show this help message and exit"
msgstr ""
#: video2x.py:108
msgid "source video file/directory"
msgstr ""
#: video2x.py:109
msgid "output video file/directory"
msgstr ""
#: video2x.py:110
msgid "video2x config file path"
msgstr ""
#: video2x.py:112
msgid "display version, lawful information and exit"
msgstr ""
#: video2x.py:115
msgid "Upscaling Options"
msgstr ""
#: video2x.py:116
msgid "upscaling driver"
msgstr ""
#: video2x.py:117
msgid "scaling ratio"
msgstr ""
#: video2x.py:118
msgid "number of processes to use for upscaling"
msgstr ""
#: video2x.py:119
msgid "preserve extracted and upscaled frames"
msgstr ""
#: video2x.py:159
msgid "This file cannot be imported"
msgstr ""
#: video2x.py:229
msgid "Program completed, taking {} seconds"
msgstr ""
#: video2x.py:232
msgid "An exception has occurred"
msgstr ""

View File

@@ -13,7 +13,7 @@ __ __ _ _ ___ __ __
Name: Video2X Controller
Creator: K4YT3X
Date Created: Feb 24, 2018
Last Modified: May 7, 2020
Last Modified: May 10, 2020
Editor: BrianPetkovsek
Last Modified: June 17, 2019
@@ -54,14 +54,11 @@ from upscaler import Upscaler
# built-in imports
import argparse
import contextlib
import gettext
import importlib
import locale
import os
import pathlib
import re
import shutil
import sys
import tempfile
import time
@@ -106,21 +103,20 @@ def parse_arguments():
parser = argparse.ArgumentParser(prog='video2x', formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
# video options
general_options = parser.add_argument_group(_('General Options'))
general_options.add_argument('-h', '--help', action='help', help=_('show this help message and exit'))
general_options.add_argument('-i', '--input', type=pathlib.Path, help=_('source video file/directory'))
general_options.add_argument('-o', '--output', type=pathlib.Path, help=_('output video file/directory'))
general_options.add_argument('-c', '--config', type=pathlib.Path, help=_('video2x config file path'), action='store',
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('-i', '--input', type=pathlib.Path, help=_('source video file/directory'))
video2x_options.add_argument('-o', '--output', type=pathlib.Path, help=_('output video file/directory'))
video2x_options.add_argument('-c', '--config', type=pathlib.Path, help=_('video2x config file path'), action='store',
default=pathlib.Path(__file__).parent.absolute() / 'video2x.yaml')
general_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_caffe')
general_options.add_argument('-p', '--processes', help=_('number of processes to use for upscaling'), action='store', type=int, default=1)
general_options.add_argument('-v', '--version', help=_('display version, lawful information and exit'), action='store_true')
video2x_options.add_argument('-v', '--version', help=_('display version, lawful information and exit'), action='store_true')
# scaling options
scaling_options = parser.add_argument_group(_('Scaling Options'))
scaling_options.add_argument('--width', help=_('output video width'), action='store', type=int)
scaling_options.add_argument('--height', help=_('output video height'), action='store', type=int)
scaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float)
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, default=2.0)
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')
# if no driver arguments are specified
if '--' not in sys.argv:
@@ -188,7 +184,18 @@ ffmpeg_settings['ffmpeg_path'] = os.path.expandvars(ffmpeg_settings['ffmpeg_path
# load video2x settings
image_format = config['video2x']['image_format'].lower()
preserve_frames = config['video2x']['preserve_frames']
video2x_cache_directory = config['video2x']['video2x_cache_directory']
# if preserve frames specified in command line
# overwrite config file options
if video2x_args.preserve_frames is True:
preserve_frames = True
# if cache directory not specified
# use default path: %TEMP%\video2x
if config['video2x']['video2x_cache_directory'] is None:
video2x_cache_directory = (pathlib.Path(tempfile.gettempdir()) / 'video2x')
else:
video2x_cache_directory = pathlib.Path(config['video2x']['video2x_cache_directory'])
# overwrite driver_settings with driver_args
if driver_args is not None:
@@ -210,8 +217,6 @@ try:
# set upscaler optional options
upscaler.driver = video2x_args.driver
upscaler.scale_width = video2x_args.width
upscaler.scale_height = video2x_args.height
upscaler.scale_ratio = video2x_args.ratio
upscaler.processes = video2x_args.processes
upscaler.video2x_cache_directory = video2x_cache_directory

View File

@@ -1,8 +1,11 @@
# Name: Video2X Configuration File
# Creator: K4YT3X
# Date Created: October 23, 2018
# Last Modified: May 8, 2020
# Items commented out are parameters handled by Video2x.
# Last Modified: May 9, 2020
# Values here are the default values. Change the value here to
# save the default value permanently.
# Items commented out are parameters irrelevant to this context
# or parameters handled by Video2X internally.
waifu2x_caffe:
path: '%LOCALAPPDATA%\video2x\waifu2x-caffe\waifu2x-caffe-cui'
tta: 0 # <0|1> 8x slower and slightly high quality
@@ -11,17 +14,17 @@ waifu2x_caffe:
crop_h: null # input image split size(height)
crop_w: null # input image split size(width)
crop_size: 128 # input image split size
output_depth: 8 # output image chaneel depth bit
output_depth: 8 # output image chanel depth bit
output_quality: -1 # output image quality
process: gpu # <cpu|gpu|cudnn> process mode
model_dir: null # path to custom model directory (don't append last / )
#scale_height: null # custom scale height
#scale_width: null # custom scale width
scale_height: 0 # custom scale height (specifying this will overwrite scale_ratio)
scale_width: 0 # custom scale width (specifying this will overwrite scale_ratio)
#scale_ratio: null # custom scale ratio
noise_level: 3 # <0|1|2|3> noise reduction level
mode: noise_scale # <noise|scale|noise_scale|auto_scale> image processing mode
output_extention: null # extention to output image file when output_path is (auto) or input_path is folder
input_extention_list: null # extention to input image file when input_path is folder
output_extention: null # extension to output image file when output_path is (auto) or input_path is folder
input_extention_list: null # extension to input image file when input_path is folder
#output_path: null # path to output image file (when input_path is folder, output_path must be folder)
#input_path: null # (required) path to input image file
waifu2x_converter_cpp:
@@ -97,6 +100,7 @@ anime4kcpp:
codec: mp4v # 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])
ffmpeg:
ffmpeg_path: '%LOCALAPPDATA%\video2x\ffmpeg-latest-win64-static\bin'
intermediate_file_name: 'intermediate.mkv'
# step 1: extract all frames from original video
# into temporary directory
video_to_frames:

View File

@@ -4,7 +4,7 @@
Creator: Video2X GUI
Author: K4YT3X
Date Created: May 5, 2020
Last Modified: May 8, 2020
Last Modified: May 10, 2020
"""
# local imports
@@ -18,6 +18,7 @@ import sys
import tempfile
import time
import traceback
import urllib
import yaml
# third-party imports
@@ -28,11 +29,11 @@ from PyQt5.QtWidgets import *
VERSION = '2.0.0'
LEGAL_INFO = f'''Video2X GUI Version: {VERSION}
Author: K4YT3X
License: GNU GPL v3
Github Page: https://github.com/k4yt3x/video2x
Contact: k4yt3x@k4yt3x.com'''
LEGAL_INFO = f'''Video2X GUI Version: {VERSION}\\
Author: K4YT3X\\
License: GNU GPL v3\\
Github Page: [https://github.com/k4yt3x/video2x](https://github.com/k4yt3x/video2x)\\
Contact: [k4yt3x@k4yt3x.com](mailto:k4yt3x@k4yt3x.com)'''
AVAILABLE_DRIVERS = {
'Waifu2X Caffe': 'waifu2x_caffe',
@@ -218,6 +219,11 @@ class Video2XMainWindow(QMainWindow):
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox')
# frame preview
self.frame_preview_show_preview_check_box = self.findChild(QCheckBox, 'framePreviewShowPreviewCheckBox')
self.frame_preview_keep_aspect_ratio_check_box = self.findChild(QCheckBox, 'framePreviewKeepAspectRatioCheckBox')
self.frame_preview_label = self.findChild(QLabel, 'framePreviewLabel')
# currently processing
self.currently_processing_label = self.findChild(QLabel, 'currentlyProcessingLabel')
self.current_progress_bar = self.findChild(QProgressBar, 'currentProgressBar')
@@ -240,6 +246,8 @@ class Video2XMainWindow(QMainWindow):
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.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_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox')
@@ -257,11 +265,16 @@ class Video2XMainWindow(QMainWindow):
self.waifu2x_converter_cpp_path_edit_button = self.findChild(QPushButton, 'waifu2xConverterCppPathSelectButton')
self.waifu2x_converter_cpp_path_edit_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_converter_cpp_path_line_edit))
self.waifu2x_converter_cpp_png_compression_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppPngCompressionSpinBox')
self.waifu2x_converter_cpp_image_quality_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppImageQualitySpinBox')
self.waifu2x_converter_cpp_block_size_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppBlockSizeSpinBox')
self.waifu2x_converter_cpp_processor_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppProcessorSpinBox')
self.waifu2x_converter_cpp_model_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModelComboBox')
self.waifu2x_converter_cpp_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppNoiseLevelSpinBox')
self.waifu2x_converter_cpp_mode_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModeComboBox')
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QCheckBox, 'disableGpuCheckBox')
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QCheckBox, 'ttaCheckBox')
self.waifu2x_converter_cpp_log_level_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppLogLevelSpinBox')
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QCheckBox, 'waifu2xConverterCppDisableGpuCheckBox')
self.waifu2x_converter_cpp_force_opencl_check_box = self.findChild(QCheckBox, 'waifu2xConverterCppForceOpenclCheckBox')
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QCheckBox, 'waifu2xConverterCppTtaCheckBox')
# waifu2x-ncnn-vulkan
self.waifu2x_ncnn_vulkan_path_line_edit = self.findChild(QLineEdit, 'waifu2xNcnnVulkanPathLineEdit')
@@ -362,8 +375,8 @@ class Video2XMainWindow(QMainWindow):
# set cache directory path
if self.config['video2x']['video2x_cache_directory'] is None:
video2x_cache_directory = str((pathlib.Path(tempfile.gettempdir()) / 'video2x').absolute())
self.cache_line_edit.setText(video2x_cache_directory)
self.config['video2x']['video2x_cache_directory'] = str((pathlib.Path(tempfile.gettempdir()) / 'video2x').absolute())
self.cache_line_edit.setText(self.config['video2x']['video2x_cache_directory'])
# load preserve frames settings
self.preserve_frames_check_box.setChecked(self.config['video2x']['preserve_frames'])
@@ -371,6 +384,8 @@ class Video2XMainWindow(QMainWindow):
# 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_mode_combo_box.setCurrentText(settings['mode'])
self.waifu2x_caffe_noise_level_spin_box.setValue(settings['noise_level'])
@@ -386,9 +401,14 @@ class Video2XMainWindow(QMainWindow):
settings = self.config['waifu2x_converter_cpp']
self.waifu2x_converter_cpp_path_line_edit.setText(str(pathlib.Path(os.path.expandvars(settings['path'])).absolute()))
self.waifu2x_converter_cpp_png_compression_spin_box.setValue(settings['png-compression'])
self.waifu2x_converter_cpp_image_quality_spin_box.setValue(settings['image-quality'])
self.waifu2x_converter_cpp_block_size_spin_box.setValue(settings['block-size'])
self.waifu2x_converter_cpp_processor_spin_box.setValue(settings['processor'])
self.waifu2x_converter_cpp_noise_level_spin_box.setValue(settings['noise-level'])
self.waifu2x_converter_cpp_mode_combo_box.setCurrentText(settings['mode'])
self.waifu2x_converter_cpp_log_level_spin_box.setValue(settings['log-level'])
self.waifu2x_converter_cpp_disable_gpu_check_box.setChecked(settings['disable-gpu'])
self.waifu2x_converter_cpp_force_opencl_check_box.setChecked(settings['force-OpenCL'])
self.waifu2x_converter_cpp_tta_check_box.setChecked(bool(settings['tta']))
# waifu2x-ncnn-vulkan
@@ -430,6 +450,8 @@ class Video2XMainWindow(QMainWindow):
def resolve_driver_settings(self):
# 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']['mode'] = self.waifu2x_caffe_mode_combo_box.currentText()
self.config['waifu2x_caffe']['noise_level'] = self.waifu2x_caffe_noise_level_spin_box.value()
@@ -445,10 +467,15 @@ class Video2XMainWindow(QMainWindow):
# waifu2x-converter-cpp
self.config['waifu2x_converter_cpp']['path'] = os.path.expandvars(self.waifu2x_converter_cpp_path_line_edit.text())
self.config['waifu2x_converter_cpp']['png-compression'] = self.waifu2x_converter_cpp_png_compression_spin_box.value()
self.config['waifu2x_converter_cpp']['image-quality'] = self.waifu2x_converter_cpp_image_quality_spin_box.value()
self.config['waifu2x_converter_cpp']['block-size'] = self.waifu2x_converter_cpp_block_size_spin_box.value()
self.config['waifu2x_converter_cpp']['processor'] = self.waifu2x_converter_cpp_processor_spin_box.value()
self.config['waifu2x_converter_cpp']['model-dir'] = str((pathlib.Path(self.config['waifu2x_converter_cpp']['path']).parent / self.waifu2x_converter_cpp_model_combo_box.currentText()).absolute())
self.config['waifu2x_converter_cpp']['noise-level'] = self.waifu2x_converter_cpp_noise_level_spin_box.value()
self.config['waifu2x_converter_cpp']['mode'] = self.waifu2x_converter_cpp_mode_combo_box.currentText()
self.config['waifu2x_converter_cpp']['log-level'] = self.waifu2x_converter_cpp_log_level_spin_box.value()
self.config['waifu2x_converter_cpp']['disable-gpu'] = bool(self.waifu2x_converter_cpp_disable_gpu_check_box.isChecked())
self.config['waifu2x_converter_cpp']['force-OpenCL'] = bool(self.waifu2x_converter_cpp_force_opencl_check_box.isChecked())
self.config['waifu2x_converter_cpp']['tta'] = int(self.waifu2x_converter_cpp_tta_check_box.isChecked())
# waifu2x-ncnn-vulkan
@@ -620,6 +647,7 @@ class Video2XMainWindow(QMainWindow):
message_box = QMessageBox(self)
message_box.setWindowTitle('About Video2X')
message_box.setIconPixmap(QtGui.QPixmap(self.video2x_icon_path).scaled(64, 64))
message_box.setTextFormat(Qt.MarkdownText)
message_box.setText(LEGAL_INFO)
message_box.exec_()
@@ -642,24 +670,21 @@ class Video2XMainWindow(QMainWindow):
message_box = QMessageBox(self)
message_box.setWindowTitle('Error')
message_box.setIcon(QMessageBox.Critical)
message_box.setTextFormat(Qt.MarkdownText)
error_message = '''Upscaler ran into an error:
{}
Check the console output for details.
When reporting an error, please include console output.'''
try:
message_box.setText(error_message.format(exception.args[0]))
except (AttributeError, IndexError):
message_box.setText(error_message.format(exception))
error_message = '''Upscaler ran into an error:\\
**{}**\\
Check the console output for details.\\
When reporting an error, please include console output.\\
You can [submit an issue on GitHub](https://github.com/k4yt3x/video2x/issues/new?assignees=K4YT3X&labels=bug&template=bug-report.md&title={}) to report this error.'''
message_box.setText(error_message.format(exception, urllib.parse.quote(str(exception))))
message_box.exec_()
def progress_monitor(self, progress_callback):
# initialize progress bar values
upscale_begin_time = time.time()
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path()))
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path()))
# keep querying upscaling process and feed information to callback signal
while self.upscaler.running:
@@ -669,12 +694,13 @@ When reporting an error, please include console output.'''
self.upscaler.total_frames,
self.upscaler.total_processed,
self.upscaler.total_videos,
self.upscaler.current_input_video))
self.upscaler.current_input_video,
self.upscaler.last_frame_upscaled))
time.sleep(1)
# upscale process will stop at 99%
# so it's set to 100 manually when all is done
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path()))
progress_callback.emit((upscale_begin_time, 0, 0, 0, 0, pathlib.Path(), pathlib.Path()))
def set_progress(self, progress_information: tuple):
upscale_begin_time = progress_information[0]
@@ -683,6 +709,7 @@ When reporting an error, please include console output.'''
total_processed = progress_information[3]
total_videos = progress_information[4]
current_input_video = progress_information[5]
last_frame_upscaled = progress_information[6]
# calculate fields based on frames and time elapsed
time_elapsed = time.time() - upscale_begin_time
@@ -705,6 +732,27 @@ When reporting an error, please include console output.'''
self.overall_progress_bar.setValue(total_processed)
self.currently_processing_label.setText('Currently Processing: {}'.format(str(current_input_video.name)))
# if show frame is checked, show preview image
if self.frame_preview_show_preview_check_box.isChecked() and last_frame_upscaled.is_file():
last_frame_pixmap = QtGui.QPixmap(str(last_frame_upscaled.absolute()))
# the -2 here behind geometry subtracts frame size from width and height
self.frame_preview_label.setPixmap(last_frame_pixmap.scaled(self.frame_preview_label.width() - 2,
self.frame_preview_label.height() - 2,
Qt.KeepAspectRatio))
# if keep aspect ratio is checked, don't stretch image
if self.frame_preview_keep_aspect_ratio_check_box.isChecked():
self.frame_preview_label.setScaledContents(False)
else:
self.frame_preview_label.setScaledContents(True)
# display image in label
self.frame_preview_label.show()
# if show frame is unchecked, clear image
elif self.frame_preview_show_preview_check_box.isChecked() is False:
self.frame_preview_label.clear()
def reset_progress_display(self):
# reset progress display UI elements
self.current_progress_bar.setMaximum(100)
@@ -727,10 +775,10 @@ When reporting an error, please include console output.'''
# resolve input and output directories from GUI
if len(self.input_table_data) == 0:
self.show_warning('Input path unspecified', standard_icon=QMessageBox.Warning)
self.show_warning('Input path unspecified')
return
if self.output_line_edit.text().strip() == '':
self.show_warning('Output path unspecified', standard_icon=QMessageBox.Warning)
self.show_warning('Output path unspecified')
return
if len(self.input_table_data) == 1:

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.12.0, 2020-05-08T20:28:53. -->
<!-- Written by QtCreator 4.12.0, 2020-05-11T04:13:22. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>718</width>
<height>740</height>
<width>667</width>
<height>768</height>
</rect>
</property>
<property name="acceptDrops">
@@ -235,99 +235,172 @@
</widget>
</item>
<item>
<widget class="QGroupBox" name="expressSettingsGroupBox">
<property name="title">
<string>Express Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<layout class="QHBoxLayout" name="driverHorizontalLayout">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGroupBox" name="expressSettingsGroupBox">
<property name="title">
<string>Express Settings</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="driverLabel">
<layout class="QHBoxLayout" name="driverHorizontalLayout">
<item>
<widget class="QLabel" name="driverLabel">
<property name="text">
<string>Driver</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="driverComboBox">
<item>
<property name="text">
<string>Waifu2X Caffe</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X Converter CPP</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>SRMD NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>Anime4KCPP</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="processesHorizontalLayout">
<item>
<widget class="QLabel" name="processesLabel">
<property name="text">
<string>Processes</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="processesSpinBox">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="scaleRatioHorizontalLayout">
<item>
<widget class="QLabel" name="scaleRatioLabel">
<property name="text">
<string>Scale Ratio</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="scaleRatioDoubleSpinBox">
<property name="minimum">
<double>0.000000000000000</double>
</property>
<property name="maximum">
<double>9999.989999999999782</double>
</property>
<property name="singleStep">
<double>0.500000000000000</double>
</property>
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="preserveFramesCheckBox">
<property name="text">
<string>Driver</string>
<string>Preserve Frames</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="driverComboBox">
<item>
<property name="text">
<string>Waifu2X Caffe</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X Converter CPP</string>
</property>
</item>
<item>
<property name="text">
<string>Waifu2X NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>SRMD NCNN Vulkan</string>
</property>
</item>
<item>
<property name="text">
<string>Anime4KCPP</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="processesHorizontalLayout">
<item>
<widget class="QLabel" name="processesLabel">
<property name="text">
<string>Processes</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="processesSpinBox">
<property name="minimum">
<number>1</number>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="scaleRatioHorizontalLayout">
</widget>
</item>
<item>
<widget class="QGroupBox" name="framePreviewGroupBox">
<property name="title">
<string>Frame Preview</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
<widget class="QLabel" name="scaleRatioLabel">
<property name="text">
<string>Scale Ratio</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="scaleRatioDoubleSpinBox">
<property name="value">
<double>2.000000000000000</double>
</property>
</widget>
<layout class="QHBoxLayout" name="framPreviewHorizontalLayout">
<item>
<layout class="QVBoxLayout" name="framePreviewOptionsVerticalLayout">
<item>
<widget class="QCheckBox" name="framePreviewShowPreviewCheckBox">
<property name="text">
<string>Show Preview</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="framePreviewKeepAspectRatioCheckBox">
<property name="text">
<string>Keep Aspect Ratio</string>
</property>
</widget>
</item>
<item>
<spacer name="framePreviewOptionsVerticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="framePreviewLabel">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="preserveFramesCheckBox">
<property name="text">
<string>Preserve Frames</string>
</property>
<property name="tristate">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
@@ -360,6 +433,42 @@
</item>
</layout>
</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="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="maximum">
<number>999999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xCaffeModeHorizontalLayout">
<item>
@@ -652,6 +761,48 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppImageQualityHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xConverterCppImageQualityLabel">
<property name="text">
<string>Image Quality</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xConverterCppImageQualitySpinBox">
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>101</number>
</property>
<property name="value">
<number>-1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppBlockSizeHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xConverterCppBlockSizeLabel">
<property name="text">
<string>Block Size</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xConverterCppBlockSizeSpinBox">
<property name="maximum">
<number>9999</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppProcessorHorizontalLayout">
<item>
@@ -696,6 +847,27 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppNoiseLevelHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xConverterCppNoiseLevelLabel">
<property name="text">
<string>Noise Level</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xConverterCppNoiseLevelSpinBox">
<property name="maximum">
<number>3</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppModeHorizontalLayout">
<item>
@@ -726,17 +898,45 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppLogLevelHorizontalLayout">
<item>
<widget class="QLabel" name="waifu2xConverterCppLogLevelLabel">
<property name="text">
<string>Log Level</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="waifu2xConverterCppLogLevelSpinBox">
<property name="maximum">
<number>4</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="waifu2xConverterCppOptionsHorizontalLayout">
<item>
<widget class="QCheckBox" name="disableGpuCheckBox">
<widget class="QCheckBox" name="waifu2xConverterCppDisableGpuCheckBox">
<property name="text">
<string>Disable GPU</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="ttaCheckBox">
<widget class="QCheckBox" name="waifu2xConverterCppForceOpenclCheckBox">
<property name="text">
<string>Force OpenCL</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="waifu2xConverterCppTtaCheckBox">
<property name="text">
<string>TTA (Test-Time Augmentation)</string>
</property>
@@ -1022,33 +1222,43 @@
<string>Anime4K CPP</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="3" column="0">
<layout class="QHBoxLayout" name="anime4kCppStrengthColorHorizontalLayout">
<item row="1" column="1">
<layout class="QHBoxLayout" name="anime4kCppPreFiltersHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppStrengthColorLabel">
<widget class="QLabel" name="anime4kCppPreFiltersLabel">
<property name="text">
<string>Strength Color</string>
<string>Pre-Filters</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="anime4kCppStrengthColorSpinBox">
<widget class="QSpinBox" name="anime4kCppPreFiltersSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<double>0.300000000000000</double>
<number>4</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="anime4kCppPathHorizontalLayout">
<item row="3" column="1">
<layout class="QHBoxLayout" name="anime4kCppPlatformIdHorizontalLayout">
<item>
<widget class="QLineEdit" name="anime4kCppPathLineEdit"/>
<widget class="QLabel" name="anime4kCppPlatformIdLabel">
<property name="text">
<string>Platform ID</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="anime4kCppPathSelectButton">
<property name="text">
<string>Select Binary Path</string>
<widget class="QSpinBox" name="anime4kCppPlatformIdSpinBox">
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
@@ -1066,7 +1276,7 @@
<item>
<widget class="QSpinBox" name="anime4kCppThreadsSpinBox">
<property name="maximum">
<number>999</number>
<number>99999</number>
</property>
<property name="value">
<number>16</number>
@@ -1075,55 +1285,25 @@
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="anime4kCppStrengthGradientHorizontalLayout">
<item row="3" column="0">
<layout class="QHBoxLayout" name="anime4kCppStrengthColorHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppStrengthGradientLabel">
<widget class="QLabel" name="anime4kCppStrengthColorLabel">
<property name="text">
<string>Strength Gradient</string>
<string>Strength Color</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="anime4kCppStrengthGradientSpinBox">
<property name="value">
<widget class="QDoubleSpinBox" name="anime4kCppStrengthColorSpinBox">
<property name="maximum">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="anime4kCppPassesHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPassesLabel">
<property name="text">
<string>Passes</string>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPassesSpinBox">
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="anime4kCppPushColorCountHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPushColorLabel">
<property name="text">
<string>Push Color Count</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPushColorCountSpinBox">
<property name="value">
<number>2</number>
<double>0.300000000000000</double>
</property>
</widget>
</item>
@@ -1166,17 +1346,21 @@
</layout>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="anime4kCppPreFiltersHorizontalLayout">
<item row="4" column="1">
<layout class="QHBoxLayout" name="anime4kCppDeviceIdHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPreFiltersLabel">
<widget class="QLabel" name="anime4kCppDeviceIdLabel">
<property name="text">
<string>Pre-Filters</string>
<string>Device ID</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPreFiltersSpinBox"/>
<widget class="QSpinBox" name="anime4kCppDeviceIdSpinBox">
<property name="maximum">
<number>99999</number>
</property>
</widget>
</item>
</layout>
</item>
@@ -1190,36 +1374,18 @@
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPostFiltersSpinBox"/>
</item>
</layout>
</item>
<item row="3" column="1">
<layout class="QHBoxLayout" name="anime4kCppPlatformIdHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPlatformIdLabel">
<property name="text">
<string>Platform ID</string>
<widget class="QSpinBox" name="anime4kCppPostFiltersSpinBox">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<number>40</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPlatformIdSpinBox"/>
</item>
</layout>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="anime4kCppDeviceIdHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppDeviceIdLabel">
<property name="text">
<string>Device ID</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppDeviceIdSpinBox"/>
</item>
</layout>
</item>
<item row="7" column="1">
@@ -1267,6 +1433,86 @@
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="anime4kCppPassesHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPassesLabel">
<property name="text">
<string>Passes</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPassesSpinBox">
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="anime4kCppPathHorizontalLayout">
<item>
<widget class="QLineEdit" name="anime4kCppPathLineEdit"/>
</item>
<item>
<widget class="QPushButton" name="anime4kCppPathSelectButton">
<property name="text">
<string>Select Binary Path</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="anime4kCppPushColorCountHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppPushColorLabel">
<property name="text">
<string>Push Color Count</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="anime4kCppPushColorCountSpinBox">
<property name="maximum">
<number>99999</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<layout class="QHBoxLayout" name="anime4kCppStrengthGradientHorizontalLayout">
<item>
<widget class="QLabel" name="anime4kCppStrengthGradientLabel">
<property name="text">
<string>Strength Gradient</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="anime4kCppStrengthGradientSpinBox">
<property name="maximum">
<double>1.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
@@ -1462,7 +1708,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>718</width>
<width>667</width>
<height>21</height>
</rect>
</property>

View File

@@ -4,7 +4,7 @@
Name: Waifu2x Caffe Driver
Author: K4YT3X
Date Created: May 3, 2020
Last Modified: May 7, 2020
Last Modified: May 11, 2020
Description: This class is a high-level wrapper
for waifu2x-caffe.
@@ -31,17 +31,24 @@ class WrapperMain:
self.driver_settings = driver_settings
self.print_lock = threading.Lock()
@staticmethod
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')
return value
@staticmethod
def parse_arguments(arguments):
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=pathlib.Path, help='File for loading')
# parser.add_argument('-o', '--output', type=pathlib.Path, help='File for outputting')
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=float, help='Strength for pushing color,range 0 to 1,higher for thinner')
parser.add_argument('-g', '--strengthGradient', type=float, help='Strength for pushing gradient,range 0 to 1,higher for sharper')
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')
@@ -58,7 +65,11 @@ class WrapperMain:
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])')
return parser.parse_args(arguments)
def upscale(self, input_file, output_file, zoom_factor, threads):
def load_configurations(self, upscaler):
self.driver_settings['zoomFactor'] = upscaler.scale_ratio
self.driver_settings['threads'] = upscaler.processes
def upscale(self, input_file, output_file):
"""This is the core function for WAIFU2X class
Arguments:
@@ -71,8 +82,6 @@ class WrapperMain:
# overwrite config file settings
self.driver_settings['input'] = input_file
self.driver_settings['output'] = output_file
self.driver_settings['zoomFactor'] = zoom_factor
self.driver_settings['threads'] = threads
# Anime4KCPP will look for Anime4KCPPKernel.cl under the current working directory
# change the CWD to its containing directory so it will find it

View File

@@ -4,7 +4,7 @@
Name: Video2X FFmpeg Controller
Author: K4YT3X
Date Created: Feb 24, 2018
Last Modified: May 7, 2020
Last Modified: May 9, 2020
Description: This class handles all FFmpeg related operations.
"""
@@ -32,7 +32,10 @@ class Ffmpeg:
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.image_format = image_format
self.intermediate_file_name = pathlib.Path(self.ffmpeg_settings['intermediate_file_name'])
self.pixel_format = None
def get_pixel_formats(self):
@@ -133,7 +136,7 @@ class Ffmpeg:
return(self._execute(execute))
def convert_video(self, framerate, resolution, upscaled_frames):
def assemble_video(self, framerate, resolution, upscaled_frames):
"""Converts images into videos
This method converts a set of images into a video
@@ -177,12 +180,12 @@ class Ffmpeg:
# specify output file location
execute.extend([
upscaled_frames / 'no_audio.mp4'
upscaled_frames / self.intermediate_file_name
])
return(self._execute(execute))
def migrate_audio_tracks_subtitles(self, input_video, output_video, upscaled_frames):
def migrate_streams(self, input_video, output_video, upscaled_frames):
""" Migrates audio tracks and subtitles from input video to output video
Arguments:
@@ -198,7 +201,7 @@ class Ffmpeg:
execute.extend([
'-i',
upscaled_frames / 'no_audio.mp4',
upscaled_frames / self.intermediate_file_name,
'-i',
input_video
])

View File

@@ -4,7 +4,7 @@
Name: SRMD NCNN Vulkan Driver
Creator: K4YT3X
Date Created: April 26, 2020
Last Modified: May 7, 2020
Last Modified: May 11, 2020
Description: This class is a high-level wrapper
for srmd_ncnn_vulkan.
@@ -42,8 +42,8 @@ class WrapperMain:
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=pathlib.Path, help='input image path (jpg/png) or directory')
# parser.add_argument('-o', type=pathlib.Path, help='output image path (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('-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('-t', type=int, help='tile size (>=32)')
@@ -53,7 +53,11 @@ class WrapperMain:
parser.add_argument('-x', action='store_true', help='enable tta mode')
return parser.parse_args(arguments)
def upscale(self, input_directory, output_directory, scale_ratio):
def load_configurations(self, upscaler):
self.driver_settings['s'] = int(upscaler.scale_ratio)
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
def upscale(self, input_directory, output_directory):
"""This is the core function for SRMD ncnn Vulkan class
Arguments:
@@ -65,7 +69,6 @@ class WrapperMain:
# overwrite config file settings
self.driver_settings['i'] = input_directory
self.driver_settings['o'] = output_directory
self.driver_settings['s'] = scale_ratio
# 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

View File

@@ -4,7 +4,7 @@
Name: Waifu2x Caffe Driver
Author: K4YT3X
Date Created: Feb 24, 2018
Last Modified: May 7, 2020
Last Modified: May 11, 2020
Description: This class is a high-level wrapper
for waifu2x-caffe.
@@ -53,36 +53,30 @@ class WrapperMain:
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'], help='image processing mode')
parser.add_argument('-e', '--output_extension', type=str, help='extention to output image file when output_path is (auto) or input_path is folder')
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', type=pathlib.Path, help='path to output image file (when input_path is folder, output_path must be folder)')
# parser.add_argument('-i', '--input_file', type=pathlib.Path, help='(required) path to input image file')
parser.add_argument('-o', '--output', 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_file', type=str, help=argparse.SUPPRESS) # help='(required) path to input image file')
return parser.parse_args(arguments)
def upscale(self, input_directory, output_directory, scale_ratio, scale_width, scale_height, image_format, bit_depth):
"""This is the core function for WAIFU2X class
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.image_format
Arguments:
input_directory {string} -- source directory path
output_directory {string} -- output directory path
width {int} -- output video width
height {int} -- output video height
# bit_depth will be 12 at this point
# it will up updated later
self.driver_settings['output_depth'] = 12
def upscale(self, input_directory, output_directory):
""" start upscaling process
"""
# overwrite config file settings
self.driver_settings['input_path'] = input_directory
self.driver_settings['output_path'] = output_directory
if scale_ratio:
self.driver_settings['scale_ratio'] = scale_ratio
elif scale_width and scale_height:
self.driver_settings['scale_width'] = scale_width
self.driver_settings['scale_height'] = scale_height
self.driver_settings['output_extention'] = image_format
self.driver_settings['output_depth'] = bit_depth
# list to be executed
# initialize the list with waifu2x binary path as the first element
execute = [self.driver_settings.pop('path')]

View File

@@ -4,7 +4,7 @@
Name: Waifu2x Converter CPP Driver
Author: K4YT3X
Date Created: February 8, 2019
Last Modified: May 7, 2020
Last Modified: May 11, 2020
Description: This class is a high-level wrapper
for waifu2x-converter-cpp.
@@ -61,12 +61,17 @@ class WrapperMain:
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=pathlib.Pathh, help='path to output image file or directory (you should use the full path)')
# parser.add_argument('-i', '--input', type=pathlib.Path, help='(required) path to input image file or directory (you should use the full path)')
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)
def upscale(self, input_directory, output_directory, scale_ratio, jobs, image_format):
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.image_format.lower()
def upscale(self, input_directory, output_directory):
""" Waifu2x Converter Driver Upscaler
This method executes the upscaling of extracted frames.
@@ -80,9 +85,6 @@ class WrapperMain:
# overwrite config file settings
self.driver_settings['input'] = input_directory
self.driver_settings['output'] = output_directory
self.driver_settings['scale-ratio'] = scale_ratio
self.driver_settings['jobs'] = jobs
self.driver_settings['output-format'] = image_format
# models_rgb must be specified manually for waifu2x-converter-cpp
# if it's not specified in the arguments, create automatically

View File

@@ -4,7 +4,7 @@
Name: Waifu2x NCNN Vulkan Driver
Creator: SAT3LL
Date Created: June 26, 2019
Last Modified: May 7, 2020
Last Modified: May 11, 2020
Editor: K4YT3X
Last Modified: February 22, 2020
@@ -45,8 +45,8 @@ class WrapperMain:
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=pathlib.Path, help='input image path (jpg/png) or directory')
# parser.add_argument('-o', type=pathlib.Path, help='output image path (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('-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('-t', type=int, help='tile size (>=32)')
@@ -56,7 +56,11 @@ class WrapperMain:
parser.add_argument('-x', action='store_true', help='enable tta mode')
return parser.parse_args(arguments)
def upscale(self, input_directory, output_directory, scale_ratio):
def load_configurations(self, upscaler):
self.driver_settings['s'] = int(upscaler.scale_ratio)
self.driver_settings['j'] = '{}:{}:{}'.format(upscaler.processes, upscaler.processes, upscaler.processes)
def upscale(self, input_directory, output_directory):
"""This is the core function for WAIFU2X class
Arguments:
@@ -68,7 +72,6 @@ class WrapperMain:
# overwrite config file settings
self.driver_settings['i'] = input_directory
self.driver_settings['o'] = output_directory
self.driver_settings['s'] = int(scale_ratio)
# 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