mirror of
https://github.com/lltcggie/waifu2x-caffe.git
synced 2025-06-26 13:42:48 +00:00
Merge branch 'upconv'
# Conflicts: # bin/lang/english.json # bin/lang/japanese.json # common/waifu2x.cpp # common/waifu2x.h # waifu2x-caffe-gui/MainDialog.cpp # waifu2x-caffe-gui/Resource.rc # waifu2x-caffe-gui/resource.h
This commit is contained in:
commit
485213433b
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
247
.gitignore
vendored
Normal file
247
.gitignore
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
|
||||
# User-specific files
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
[Xx]64/
|
||||
[Xx]86/
|
||||
[Bb]uild/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
|
||||
# Visual Studio 2015 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# DNX
|
||||
project.lock.json
|
||||
artifacts/
|
||||
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
|
||||
# TODO: Un-comment the next line if you do not want to checkin
|
||||
# your web deploy settings because they may include unencrypted
|
||||
# passwords
|
||||
#*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/packages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/packages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/packages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignoreable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Microsoft Azure ApplicationInsights config file
|
||||
ApplicationInsights.config
|
||||
|
||||
# Windows Store app package directory
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
[Ss]tyle[Cc]op.*
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
node_modules/
|
||||
orleans.codegen.cs
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# LightSwitch generated files
|
||||
GeneratedArtifacts/
|
||||
ModelManifest.xml
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
*.caffemodel
|
||||
*.protobin
|
@ -153,6 +153,7 @@ cuDNN
|
||||
変換対象の画像によって最適なモデルは異なるので、様々なモデルを試してみることをおすすめします。
|
||||
* 2次元イラスト(RGBモデル) : 画像のRGBすべてを変換する2次元イラスト用モデル
|
||||
* 写真・アニメ(Photoモデル) : 写真・アニメ用のモデル
|
||||
* 2次元イラスト(UpRGBモデル) : 2次元イラスト(RGBモデル)より高速かつ同等以上の画質で変換するモデル。ただしRGBモデルより消費するメモリ(VRAM)の量が多いので、変換中に強制終了する場合は分割サイズを調節すること
|
||||
* 2次元イラスト(Yモデル) : 画像の輝度のみを変換する2次元イラスト用モデル
|
||||
|
||||
###「TTAモードを使う」
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"仅放大",
|
||||
"IDC_RADIO_MODE_NOISE":"仅降噪",
|
||||
"IDC_RADIO_AUTO_SCALE":"自动降噪和放大",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEG 降噪等级",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"降噪等级",
|
||||
"IDC_RADIONOISE_LEVEL1":"1 级",
|
||||
"IDC_RADIONOISE_LEVEL2":"2 级",
|
||||
"IDC_RADIONOISE_LEVEL3":"3 级",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"放大",
|
||||
"IDC_RADIO_MODE_NOISE":"降噪",
|
||||
"IDC_RADIO_AUTO_SCALE":"自動降噪和放大",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEG降噪水平",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"降噪水平",
|
||||
"IDC_RADIONOISE_LEVEL1":"等級1",
|
||||
"IDC_RADIONOISE_LEVEL2":"等級2",
|
||||
"IDC_RADIONOISE_LEVEL3":"等級3",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"Magnify only",
|
||||
"IDC_RADIO_MODE_NOISE":"Denoise only",
|
||||
"IDC_RADIO_AUTO_SCALE":"Magnify && Auto Denoise",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEG denoise level",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"Denoise level",
|
||||
"IDC_RADIONOISE_LEVEL1":"Level 1",
|
||||
"IDC_RADIONOISE_LEVEL2":"Level 2",
|
||||
"IDC_RADIONOISE_LEVEL3":"Level 3",
|
||||
@ -91,5 +91,6 @@
|
||||
"MessageCudaOldDeviceError":"Your CUDA device too old.\r\nPlease use Compute Capability 2.0 or more devices",
|
||||
"OK":"OK",
|
||||
"Cancel":"Cancel",
|
||||
"IDC_STATIC_USE_GPU_NO":"Use GPU No"
|
||||
"IDC_STATIC_USE_GPU_NO":"Use GPU No",
|
||||
"IDC_RADIO_MODEL_UPCONV_RGB":"2-D illust (UpRGB Model)"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"拡大",
|
||||
"IDC_RADIO_MODE_NOISE":"ノイズ除去",
|
||||
"IDC_RADIO_AUTO_SCALE":"ノイズ除去(自動判別)と拡大",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEGノイズ除去レベル",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"ノイズ除去レベル",
|
||||
"IDC_RADIONOISE_LEVEL1":"レベル1",
|
||||
"IDC_RADIONOISE_LEVEL2":"レベル2",
|
||||
"IDC_RADIONOISE_LEVEL3":"レベル3",
|
||||
@ -28,7 +28,7 @@
|
||||
"IDC_STATIC_MODEL":"モデル",
|
||||
"IDC_RADIO_MODEL_RGB":"2次元イラスト (RGBモデル)",
|
||||
"IDC_RADIO_MODEL_PHOTO":"写真・アニメ (Photoモデル)",
|
||||
"IDC_RADIO_MODEL_Y":"2次元イラスト2 (Yモデル)",
|
||||
"IDC_RADIO_MODEL_Y":"2次元イラスト (Yモデル)",
|
||||
"IDC_CHECK_TTA":"TTAモードを使う",
|
||||
"IDC_STATIC_PROCESS_SPEED_SETTING":"処理速度設定",
|
||||
"IDC_STATIC_PROCESSOR":"使用プロセッサー",
|
||||
@ -91,5 +91,6 @@
|
||||
"MessageCudaOldDeviceError":"CUDAデバイスが古いです。\r\nCompute Capability 2.0以上のデバイスを使用してください",
|
||||
"OK":"OK",
|
||||
"Cancel":"キャンセル",
|
||||
"IDC_STATIC_USE_GPU_NO":"使用GPU No"
|
||||
"IDC_STATIC_USE_GPU_NO":"使用GPU No",
|
||||
"IDC_RADIO_MODEL_UPCONV_RGB":"2次元イラスト (UpRGBモデル)"
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"확대",
|
||||
"IDC_RADIO_MODE_NOISE":"노이즈 제거",
|
||||
"IDC_RADIO_AUTO_SCALE":"자동 노이즈 제거 && 확대",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEG 노이즈 제거 단계",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"노이즈 제거 단계",
|
||||
"IDC_RADIONOISE_LEVEL1":"1단계",
|
||||
"IDC_RADIONOISE_LEVEL2":"2단계",
|
||||
"IDC_RADIONOISE_LEVEL3":"3단계",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"IDC_RADIO_MODE_SCALE":"Sadece büyüt",
|
||||
"IDC_RADIO_MODE_NOISE":"Sadece gürültüsüzleştir",
|
||||
"IDC_RADIO_AUTO_SCALE":"Büyüt ve Oto-Gürültüsüzleştir",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"JPEG gürültüsüzleştirme düzeyi",
|
||||
"IDC_STATIC_JPEG_NOISE_LEVEL":"gürültüsüzleştirme düzeyi",
|
||||
"IDC_RADIONOISE_LEVEL1":"Seviye 1",
|
||||
"IDC_RADIONOISE_LEVEL2":"Seviye 2",
|
||||
"IDC_RADIONOISE_LEVEL3":"Seviye 3",
|
||||
|
1
bin/models/anime_style_art/info.json
Normal file
1
bin/models/anime_style_art/info.json
Normal file
@ -0,0 +1 @@
|
||||
{"name":"Y","arch_name":"vgg_7","scale_factor":1,"channels":1,"offset":7}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
194
bin/models/anime_style_art/noise2_model.prototxt
Normal file
194
bin/models/anime_style_art/noise2_model.prototxt
Normal file
@ -0,0 +1,194 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 1 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
194
bin/models/anime_style_art/noise3_model.prototxt
Normal file
194
bin/models/anime_style_art/noise3_model.prototxt
Normal file
@ -0,0 +1,194 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 1 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
194
bin/models/anime_style_art/scale2.0x_model.prototxt
Normal file
194
bin/models/anime_style_art/scale2.0x_model.prototxt
Normal file
@ -0,0 +1,194 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 1 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 1
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
group: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
Binary file not shown.
1
bin/models/anime_style_art_rgb/info.json
Normal file
1
bin/models/anime_style_art_rgb/info.json
Normal file
@ -0,0 +1 @@
|
||||
{"name":"RGB","arch_name":"vgg_7","scale_factor":1,"channels":3,"offset":7}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/anime_style_art_rgb/scale2.0x_model.prototxt
Normal file
187
bin/models/anime_style_art_rgb/scale2.0x_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
Binary file not shown.
1
bin/models/photo/info.json
Normal file
1
bin/models/photo/info.json
Normal file
@ -0,0 +1 @@
|
||||
{"name":"Photo","arch_name":"vgg_7","scale_factor":1,"channels":3,"offset":7}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/photo/noise1_model.prototxt
Normal file
187
bin/models/photo/noise1_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/photo/noise2_model.prototxt
Normal file
187
bin/models/photo/noise2_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/photo/noise3_model.prototxt
Normal file
187
bin/models/photo/noise3_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/photo/scale2.0x_model.prototxt
Normal file
187
bin/models/photo/scale2.0x_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
Binary file not shown.
1
bin/models/ukbench/info.json
Normal file
1
bin/models/ukbench/info.json
Normal file
@ -0,0 +1 @@
|
||||
{"name":"ukbench","arch_name":"vgg_7","scale_factor":1,"channels":3,"offset":7}
|
File diff suppressed because one or more lines are too long
Binary file not shown.
187
bin/models/ukbench/scale2.0x_model.prototxt
Normal file
187
bin/models/ukbench/scale2.0x_model.prototxt
Normal file
@ -0,0 +1,187 @@
|
||||
name: "srcnn"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 1
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
Binary file not shown.
4
bin/models/upconv_7_anime_style_art_rgb/info.json
Normal file
4
bin/models/upconv_7_anime_style_art_rgb/info.json
Normal file
@ -0,0 +1,4 @@
|
||||
{"name":"UpRGB","arch_name":"upconv_7","has_noise_scale":true,"channels":3,
|
||||
"scale_factor":2,"offset":14,
|
||||
"scale_factor_noise":1,"offset_noise":7
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,188 @@
|
||||
name: "upconv_7"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 16
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Deconvolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
pad: 3
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 3
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,188 @@
|
||||
name: "upconv_7"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 16
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Deconvolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
pad: 3
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 3
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,188 @@
|
||||
name: "upconv_7"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 16
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Deconvolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
pad: 3
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 3
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
File diff suppressed because one or more lines are too long
188
bin/models/upconv_7_anime_style_art_rgb/scale2.0x_model.prototxt
Normal file
188
bin/models/upconv_7_anime_style_art_rgb/scale2.0x_model.prototxt
Normal file
@ -0,0 +1,188 @@
|
||||
name: "upconv_7"
|
||||
layer {
|
||||
name: "input"
|
||||
type: "Input"
|
||||
top: "input"
|
||||
input_param { shape: { dim: 1 dim: 3 dim: 142 dim: 142 } }
|
||||
}
|
||||
layer {
|
||||
name: "conv1_layer"
|
||||
type: "Convolution"
|
||||
bottom: "input"
|
||||
top: "conv1"
|
||||
convolution_param {
|
||||
num_output: 16
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv1_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv1"
|
||||
top: "conv1"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv1"
|
||||
top: "conv2"
|
||||
convolution_param {
|
||||
num_output: 32
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv2_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv2"
|
||||
top: "conv2"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv2"
|
||||
top: "conv3"
|
||||
convolution_param {
|
||||
num_output: 64
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv3_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv3"
|
||||
top: "conv3"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv3"
|
||||
top: "conv4"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv4_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv4"
|
||||
top: "conv4"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv4"
|
||||
top: "conv5"
|
||||
convolution_param {
|
||||
num_output: 128
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv5_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv5"
|
||||
top: "conv5"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_layer"
|
||||
type: "Convolution"
|
||||
bottom: "conv5"
|
||||
top: "conv6"
|
||||
convolution_param {
|
||||
num_output: 256
|
||||
kernel_size: 3
|
||||
stride: 1
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv6_relu_layer"
|
||||
type: "ReLU"
|
||||
bottom: "conv6"
|
||||
top: "conv6"
|
||||
relu_param {
|
||||
negative_slope: 0.1
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "conv7_layer"
|
||||
type: "Deconvolution"
|
||||
bottom: "conv6"
|
||||
top: "conv7"
|
||||
convolution_param {
|
||||
num_output: 3
|
||||
kernel_size: 4
|
||||
stride: 2
|
||||
pad: 3
|
||||
weight_filler {
|
||||
type: "gaussian"
|
||||
std: 0.01
|
||||
}
|
||||
}
|
||||
}
|
||||
layer {
|
||||
name: "target"
|
||||
type: "MemoryData"
|
||||
top: "target"
|
||||
top: "dummy_label2"
|
||||
memory_data_param {
|
||||
batch_size: 1
|
||||
channels: 3
|
||||
height: 142
|
||||
width: 142
|
||||
}
|
||||
include: { phase: TRAIN }
|
||||
}
|
||||
layer {
|
||||
name: "loss"
|
||||
type: "EuclideanLoss"
|
||||
bottom: "conv7"
|
||||
bottom: "target"
|
||||
top: "loss"
|
||||
include: { phase: TRAIN }
|
||||
}
|
817
common/cNet.cpp
Normal file
817
common/cNet.cpp
Normal file
@ -0,0 +1,817 @@
|
||||
#include "cNet.h"
|
||||
#include <caffe/caffe.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||
#include <google/protobuf/text_format.h>
|
||||
#include <rapidjson/document.h>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
const int kProtoReadBytesLimit = INT_MAX; // Max size of 2 GB minus 1 byte.
|
||||
|
||||
|
||||
template<typename BufType>
|
||||
static bool readFile(boost::iostreams::stream<boost::iostreams::file_descriptor_source> &is, std::vector<BufType> &buf)
|
||||
{
|
||||
if (!is)
|
||||
return false;
|
||||
|
||||
const auto size = is.seekg(0, std::ios::end).tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
|
||||
buf.resize((size / sizeof(BufType)) + (size % sizeof(BufType)));
|
||||
is.read(buf.data(), size);
|
||||
if (is.gcount() != size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename BufType>
|
||||
static bool readFile(const boost::filesystem::path &path, std::vector<BufType> &buf)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(path, std::ios_base::in | std::ios_base::binary);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return readFile(is, buf);
|
||||
}
|
||||
|
||||
static Waifu2x::eWaifu2xError readProtoText(const boost::filesystem::path &path, ::google::protobuf::Message* proto)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(path, std::ios_base::in);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
}
|
||||
|
||||
if (!is)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
|
||||
std::vector<char> tmp;
|
||||
if (!readFile(is, tmp))
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
google::protobuf::io::ArrayInputStream input(tmp.data(), tmp.size());
|
||||
const bool success = google::protobuf::TextFormat::Parse(&input, proto);
|
||||
|
||||
if (!success)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
static Waifu2x::eWaifu2xError writeProtoBinary(const ::google::protobuf::Message& proto, const boost::filesystem::path &path)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor> os;
|
||||
|
||||
try
|
||||
{
|
||||
os.open(path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
}
|
||||
|
||||
if (!os)
|
||||
return Waifu2x::eWaifu2xError_FailedWriteModelFile;
|
||||
|
||||
if (!proto.SerializePartialToOstream(&os))
|
||||
return Waifu2x::eWaifu2xError_FailedWriteModelFile;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
static Waifu2x::eWaifu2xError readProtoBinary(const boost::filesystem::path &path, ::google::protobuf::Message* proto)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(path, std::ios_base::in | std::ios_base::binary);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
}
|
||||
|
||||
if (!is)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
|
||||
std::vector<char> tmp;
|
||||
if (!readFile(is, tmp))
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
google::protobuf::io::ArrayInputStream input(tmp.data(), tmp.size());
|
||||
|
||||
google::protobuf::io::CodedInputStream coded_input(&input);
|
||||
coded_input.SetTotalBytesLimit(kProtoReadBytesLimit, 536870912);
|
||||
|
||||
const bool success = proto->ParseFromCodedStream(&coded_input);
|
||||
if (!success)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
Waifu2x::eWaifu2xError ReadJson(const boost::filesystem::path &info_path, rapidjson::Document &d, std::vector<char> &jsonBuf)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(info_path, std::ios_base::in | std::ios_base::binary);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
}
|
||||
|
||||
if (!is)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
|
||||
const size_t size = is.seekg(0, std::ios::end).tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
|
||||
jsonBuf.resize(size + 1);
|
||||
is.read(jsonBuf.data(), jsonBuf.size());
|
||||
|
||||
jsonBuf[jsonBuf.size() - 1] = '\0';
|
||||
|
||||
d.Parse(jsonBuf.data());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
cNet::cNet() : mModelScale(0), mInnerScale(0), mNetOffset(0), mInputPlane(0), mHasNoiseScaleModel(false)
|
||||
{}
|
||||
|
||||
cNet::~cNet()
|
||||
{}
|
||||
|
||||
Waifu2x::eWaifu2xError cNet::GetInfo(const boost::filesystem::path & info_path, stInfo &info)
|
||||
{
|
||||
rapidjson::Document d;
|
||||
std::vector<char> jsonBuf;
|
||||
|
||||
try
|
||||
{
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
ret = ReadJson(info_path, d, jsonBuf);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
const auto name = d["name"].GetString();
|
||||
const auto arch_name = d["arch_name"].GetString();
|
||||
const bool has_noise_scale = d.HasMember("has_noise_scale") && d["has_noise_scale"].GetBool() ? true : false;
|
||||
const int channels = d["channels"].GetInt();
|
||||
|
||||
info.name = name;
|
||||
info.arch_name = arch_name;
|
||||
info.has_noise_scale = has_noise_scale;
|
||||
info.channels = channels;
|
||||
|
||||
if (d.HasMember("offset"))
|
||||
{
|
||||
const int offset = d["offset"].GetInt();
|
||||
|
||||
info.noise.offset = offset;
|
||||
info.scale.offset = offset;
|
||||
info.noise_scale.offset = offset;
|
||||
}
|
||||
|
||||
if (d.HasMember("scale_factor"))
|
||||
{
|
||||
const int scale_factor = d["scale_factor"].GetInt();
|
||||
|
||||
info.noise.scale_factor = scale_factor;
|
||||
info.scale.scale_factor = scale_factor;
|
||||
info.noise_scale.scale_factor = scale_factor;
|
||||
}
|
||||
|
||||
if (d.HasMember("offset_noise"))
|
||||
{
|
||||
const int offset = d["offset_noise"].GetInt();
|
||||
info.noise.offset = offset;
|
||||
}
|
||||
|
||||
if (d.HasMember("scale_factor_noise"))
|
||||
{
|
||||
const int scale_factor = d["scale_factor_noise"].GetInt();
|
||||
info.noise.scale_factor = scale_factor;
|
||||
}
|
||||
|
||||
if (d.HasMember("offset_scale"))
|
||||
{
|
||||
const int offset = d["offset_scale"].GetInt();
|
||||
info.scale.offset = offset;
|
||||
}
|
||||
|
||||
if (d.HasMember("scale_factor_scale"))
|
||||
{
|
||||
const int scale_factor = d["scale_factor_scale"].GetInt();
|
||||
info.scale.scale_factor = scale_factor;
|
||||
}
|
||||
|
||||
if (d.HasMember("offset_noise_scale"))
|
||||
{
|
||||
const int offset = d["offset_noise_scale"].GetInt();
|
||||
info.noise_scale.offset = offset;
|
||||
}
|
||||
|
||||
if (d.HasMember("scale_factor_noise_scale"))
|
||||
{
|
||||
const int scale_factor = d["scale_factor_noise_scale"].GetInt();
|
||||
info.noise_scale.scale_factor = scale_factor;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
// モデルファイルからネットワークを構築
|
||||
// processでcudnnが指定されなかった場合はcuDNNが呼び出されないように変更する
|
||||
Waifu2x::eWaifu2xError cNet::ConstractNet(const Waifu2x::eWaifu2xModelType mode, const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path, const stInfo &info, const std::string &process)
|
||||
{
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
mMode = mode;
|
||||
|
||||
LoadParamFromInfo(mode, info);
|
||||
|
||||
boost::filesystem::path modelbin_path = model_path;
|
||||
modelbin_path += ".protobin";
|
||||
boost::filesystem::path caffemodel_path = param_path;
|
||||
caffemodel_path += ".caffemodel";
|
||||
|
||||
caffe::NetParameter param_model;
|
||||
caffe::NetParameter param_caffemodel;
|
||||
|
||||
const auto retModelBin = readProtoBinary(modelbin_path, ¶m_model);
|
||||
const auto retParamBin = readProtoBinary(caffemodel_path, ¶m_caffemodel);
|
||||
|
||||
if (retModelBin == Waifu2x::eWaifu2xError_OK && retParamBin == Waifu2x::eWaifu2xError_OK)
|
||||
{
|
||||
ret = SetParameter(param_model, process);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
if (!caffe::UpgradeNetAsNeeded(caffemodel_path.string(), ¶m_caffemodel))
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
mNet = boost::shared_ptr<caffe::Net<float>>(new caffe::Net<float>(param_model));
|
||||
mNet->CopyTrainedLayersFrom(param_caffemodel);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto ret = LoadParameterFromJson(model_path, param_path, modelbin_path, caffemodel_path, process);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
}
|
||||
|
||||
const auto &inputs = mNet->input_blobs();
|
||||
if (inputs.empty())
|
||||
return Waifu2x::eWaifu2xError_FailedConstructModel;
|
||||
|
||||
if (mInputPlane != inputs[0]->channels())
|
||||
return Waifu2x::eWaifu2xError_FailedConstructModel;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
void cNet::LoadParamFromInfo(const Waifu2x::eWaifu2xModelType mode, const stInfo &info)
|
||||
{
|
||||
mModelScale = 2; // TODO: 動的に設定するようにする
|
||||
|
||||
stInfo::stParam param;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case Waifu2x::eWaifu2xModelTypeNoise:
|
||||
param = info.noise;
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeScale:
|
||||
param = info.scale;
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeNoiseScale:
|
||||
param = info.noise_scale;
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeAutoScale:
|
||||
param = info.noise_scale;
|
||||
break;
|
||||
}
|
||||
|
||||
mInnerScale = param.scale_factor;
|
||||
mNetOffset = param.offset;
|
||||
mInputPlane = info.channels;
|
||||
mHasNoiseScaleModel = info.has_noise_scale;
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError cNet::SetParameter(caffe::NetParameter ¶m, const std::string &process) const
|
||||
{
|
||||
param.mutable_state()->set_phase(caffe::TEST);
|
||||
|
||||
{
|
||||
auto input_layer = param.mutable_layer(0);
|
||||
auto mid = input_layer->mutable_input_param()->mutable_shape();
|
||||
if (mid->size() != 1 || mid->Mutable(0)->dim_size() != 4)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
mid->Mutable(0)->set_dim(0, 1);
|
||||
mid->Mutable(0)->set_dim(2, 142);
|
||||
mid->Mutable(0)->set_dim(3, 142);
|
||||
}
|
||||
|
||||
for (int i = 0; i < param.layer_size(); i++)
|
||||
{
|
||||
caffe::LayerParameter *layer_param = param.mutable_layer(i);
|
||||
const std::string& type = layer_param->type();
|
||||
if (type == "Convolution")
|
||||
{
|
||||
if (process == "cudnn")
|
||||
layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CUDNN);
|
||||
else
|
||||
layer_param->mutable_convolution_param()->set_engine(caffe::ConvolutionParameter_Engine_CAFFE);
|
||||
}
|
||||
else if (type == "ReLU")
|
||||
{
|
||||
if (process == "cudnn")
|
||||
layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CUDNN);
|
||||
else
|
||||
layer_param->mutable_relu_param()->set_engine(caffe::ReLUParameter_Engine_CAFFE);
|
||||
}
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError cNet::LoadParameterFromJson(const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path
|
||||
, const boost::filesystem::path &modelbin_path, const boost::filesystem::path &caffemodel_path, const std::string &process)
|
||||
{
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
caffe::NetParameter param;
|
||||
ret = readProtoText(model_path, ¶m);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
ret = writeProtoBinary(param, modelbin_path);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
ret = SetParameter(param, process);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
mNet = boost::shared_ptr<caffe::Net<float>>(new caffe::Net<float>(param));
|
||||
|
||||
rapidjson::Document d;
|
||||
std::vector<char> jsonBuf;
|
||||
|
||||
try
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(param_path, std::ios_base::in | std::ios_base::binary);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
}
|
||||
|
||||
if (!is)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenModelFile;
|
||||
|
||||
const size_t size = is.seekg(0, std::ios::end).tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
|
||||
jsonBuf.resize(size + 1);
|
||||
is.read(jsonBuf.data(), jsonBuf.size());
|
||||
|
||||
jsonBuf[jsonBuf.size() - 1] = '\0';
|
||||
|
||||
d.Parse(jsonBuf.data());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
}
|
||||
|
||||
if (d.Size() != 7)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
int inputPlane = 0;
|
||||
int outputPlane = 0;
|
||||
try
|
||||
{
|
||||
inputPlane = d[0]["nInputPlane"].GetInt();
|
||||
outputPlane = d[d.Size() - 1]["nOutputPlane"].GetInt();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
}
|
||||
|
||||
if (inputPlane == 0 || outputPlane == 0)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
if (inputPlane != outputPlane)
|
||||
return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
//if (param.layer_size() < 17)
|
||||
// return Waifu2x::eWaifu2xError_FailedParseModelFile;
|
||||
|
||||
std::vector<boost::shared_ptr<caffe::Layer<float>>> list;
|
||||
auto &v = mNet->layers();
|
||||
for (auto &l : v)
|
||||
{
|
||||
auto lk = l->type();
|
||||
auto &bv = l->blobs();
|
||||
if (bv.size() > 0)
|
||||
list.push_back(l);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::vector<float> weightList;
|
||||
std::vector<float> biasList;
|
||||
|
||||
int count = 0;
|
||||
for (auto it = d.Begin(); it != d.End(); ++it)
|
||||
{
|
||||
const auto &weight = (*it)["weight"];
|
||||
const auto nInputPlane = (*it)["nInputPlane"].GetInt();
|
||||
const auto nOutputPlane = (*it)["nOutputPlane"].GetInt();
|
||||
const auto kW = (*it)["kW"].GetInt();
|
||||
const auto &bias = (*it)["bias"];
|
||||
|
||||
auto leyer = list[count];
|
||||
|
||||
auto &b0 = leyer->blobs()[0];
|
||||
auto &b1 = leyer->blobs()[1];
|
||||
|
||||
float *b0Ptr = nullptr;
|
||||
float *b1Ptr = nullptr;
|
||||
|
||||
if (caffe::Caffe::mode() == caffe::Caffe::CPU)
|
||||
{
|
||||
b0Ptr = b0->mutable_cpu_data();
|
||||
b1Ptr = b1->mutable_cpu_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
b0Ptr = b0->mutable_gpu_data();
|
||||
b1Ptr = b1->mutable_gpu_data();
|
||||
}
|
||||
|
||||
const auto WeightSize1 = weight.Size();
|
||||
const auto WeightSize2 = weight[0].Size();
|
||||
const auto KernelHeight = weight[0][0].Size();
|
||||
const auto KernelWidth = weight[0][0][0].Size();
|
||||
|
||||
if (!(b0->count() == WeightSize1 * WeightSize2 * KernelHeight * KernelWidth))
|
||||
return Waifu2x::eWaifu2xError_FailedConstructModel;
|
||||
|
||||
if (!(b1->count() == bias.Size()))
|
||||
return Waifu2x::eWaifu2xError_FailedConstructModel;
|
||||
|
||||
weightList.resize(0);
|
||||
biasList.resize(0);
|
||||
|
||||
size_t weightCount = 0;
|
||||
for (auto it2 = weight.Begin(); it2 != weight.End(); ++it2)
|
||||
{
|
||||
for (auto it3 = (*it2).Begin(); it3 != (*it2).End(); ++it3)
|
||||
{
|
||||
for (auto it4 = (*it3).Begin(); it4 != (*it3).End(); ++it4)
|
||||
{
|
||||
for (auto it5 = (*it4).Begin(); it5 != (*it4).End(); ++it5)
|
||||
weightList.push_back((float)it5->GetDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
caffe::caffe_copy(b0->count(), weightList.data(), b0Ptr);
|
||||
|
||||
for (auto it2 = bias.Begin(); it2 != bias.End(); ++it2)
|
||||
biasList.push_back((float)it2->GetDouble());
|
||||
|
||||
caffe::caffe_copy(b1->count(), biasList.data(), b1Ptr);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
mNet->ToProto(¶m);
|
||||
|
||||
ret = writeProtoBinary(param, caffemodel_path);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedConstructModel;
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
int cNet::GetInputPlane() const
|
||||
{
|
||||
return mInputPlane;
|
||||
}
|
||||
|
||||
int cNet::GetInnerScale() const
|
||||
{
|
||||
return mInnerScale;
|
||||
}
|
||||
|
||||
int cNet::GetNetOffset() const
|
||||
{
|
||||
return mNetOffset;
|
||||
}
|
||||
|
||||
int cNet::GetScale() const
|
||||
{
|
||||
return mModelScale;
|
||||
}
|
||||
|
||||
int cNet::GetInputMemorySize(const int crop_w, const int crop_h, const int outer_padding, const int batch_size) const
|
||||
{
|
||||
const int InputPadding = mNetOffset + outer_padding;
|
||||
const auto input_block_width = crop_w + InputPadding * 2;
|
||||
const auto input_block_height = crop_h + InputPadding * 2;
|
||||
|
||||
const int input_block_plane_size = input_block_width * input_block_height * mInputPlane;
|
||||
|
||||
return input_block_plane_size * sizeof(float);
|
||||
|
||||
}
|
||||
|
||||
int cNet::GetOutputMemorySize(const int crop_w, const int crop_h, const int outer_padding, const int batch_size) const
|
||||
{
|
||||
const int InputPadding = mNetOffset + outer_padding;
|
||||
const auto input_block_width = crop_w + InputPadding * 2;
|
||||
const auto input_block_height = crop_h + InputPadding * 2;
|
||||
|
||||
const auto output_block_width = input_block_width * mInnerScale - mNetOffset * 2;
|
||||
const auto output_block_height = input_block_height * mInnerScale - mNetOffset * 2;
|
||||
|
||||
const int output_block_plane_size = output_block_width * output_block_height * mInputPlane;
|
||||
|
||||
return output_block_plane_size * sizeof(float);
|
||||
}
|
||||
|
||||
// ネットワークを使って画像を再構築する
|
||||
Waifu2x::eWaifu2xError cNet::ReconstructImage(const bool UseTTA, const int crop_w, const int crop_h, const int outer_padding, const int batch_size, float *outputBlockBuf, const cv::Mat &inMat, cv::Mat &outMat)
|
||||
{
|
||||
const auto InputHeight = inMat.size().height;
|
||||
const auto InputWidth = inMat.size().width;
|
||||
const auto InputLine = inMat.step1();
|
||||
|
||||
assert(inMat.channels() == 1 || inMat.channels() == 3);
|
||||
|
||||
const int InputPadding = mNetOffset + outer_padding; // 入力パディング
|
||||
|
||||
const auto NoPaddingInputWidth = InputWidth - InputPadding * 2; // パディングを除いた入力画像サイズ(横)
|
||||
const auto NoPaddingInputHeight = InputHeight - InputPadding * 2; // パディングを除いた入力画像サイズ(縦)
|
||||
|
||||
cv::Mat outim(NoPaddingInputHeight * mInnerScale, NoPaddingInputWidth * mInnerScale, inMat.type());
|
||||
|
||||
// float *imptr = (float *)im.data;
|
||||
float *imptr = (float *)outim.data;
|
||||
|
||||
const auto input_block_width = crop_w + InputPadding * 2; // 入力ブロックサイズ(横)
|
||||
const auto input_block_height = crop_h + InputPadding * 2; // 入力ブロックサイズ(縦)
|
||||
|
||||
const auto output_block_width = input_block_width * mInnerScale - mNetOffset * 2; // 出力ブロックサイズ(横)
|
||||
const auto output_block_height = input_block_height * mInnerScale - mNetOffset * 2; // 出力ブロックサイズ(縦)
|
||||
|
||||
const auto output_crop_block_width = crop_w * mInnerScale; // クロップ後の出力ブロックサイズ(横)
|
||||
const auto output_crop_block_height = crop_h * mInnerScale; // クロップ後の出力ブロックサイズ(縦)
|
||||
|
||||
const auto output_crop_w = (output_block_width - crop_w * mInnerScale) / 2; // 出力後のクロップサイズ
|
||||
const auto output_crop_h = (output_block_height - crop_h * mInnerScale) / 2; // 出力後のクロップサイズ
|
||||
|
||||
assert(NoPaddingInputWidth % crop_w == 0);
|
||||
assert(NoPaddingInputHeight % crop_h == 0);
|
||||
|
||||
try
|
||||
{
|
||||
auto input_blobs = mNet->input_blobs();
|
||||
|
||||
assert(input_blobs.size() > 0);
|
||||
|
||||
auto input_blob = mNet->input_blobs()[0];
|
||||
|
||||
input_blob->Reshape(batch_size, mInputPlane, input_block_height, input_block_width);
|
||||
|
||||
assert(inMat.channels() == mInputPlane);
|
||||
assert(input_blob->shape(1) == mInputPlane);
|
||||
|
||||
const int WidthNum = NoPaddingInputWidth / crop_w;
|
||||
const int HeightNum = NoPaddingInputHeight / crop_h;
|
||||
|
||||
const int BlockNum = WidthNum * HeightNum;
|
||||
|
||||
const int input_block_plane_size = input_block_width * input_block_height * mInputPlane;
|
||||
const int output_block_plane_size = output_block_width * output_block_height * mInputPlane;
|
||||
|
||||
// 画像は(消費メモリの都合上)block_size*block_sizeに分けて再構築する
|
||||
for (int num = 0; num < BlockNum; num += batch_size)
|
||||
{
|
||||
const int processNum = (BlockNum - num) >= batch_size ? batch_size : BlockNum - num;
|
||||
|
||||
if (processNum < batch_size)
|
||||
input_blob->Reshape(processNum, mInputPlane, input_block_height, input_block_width);
|
||||
|
||||
for (int n = 0; n < processNum; n++)
|
||||
{
|
||||
const int wn = (num + n) % WidthNum;
|
||||
const int hn = (num + n) / WidthNum;
|
||||
|
||||
const int w = wn * crop_w;
|
||||
const int h = hn * crop_h;
|
||||
|
||||
assert(w + input_block_width <= InputWidth && h + input_block_height <= InputHeight);
|
||||
|
||||
cv::Mat someimg = inMat(cv::Rect(w, h, input_block_width, input_block_height));
|
||||
|
||||
// 画像を直列に変換
|
||||
{
|
||||
float *fptr = input_blob->mutable_cpu_data() + (input_block_plane_size * n);
|
||||
const float *uptr = (const float *)someimg.data;
|
||||
|
||||
const auto Line = someimg.step1();
|
||||
|
||||
if (someimg.channels() == 1)
|
||||
{
|
||||
if (input_block_width == Line)
|
||||
memcpy(fptr, uptr, input_block_width * input_block_height * sizeof(float));
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < input_block_height; i++)
|
||||
memcpy(fptr + i * input_block_width, uptr + i * Line, input_block_width * sizeof(float));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto LinePixel = someimg.step1() / someimg.channels();
|
||||
const auto Channel = someimg.channels();
|
||||
const auto Width = someimg.size().width;
|
||||
const auto Height = someimg.size().height;
|
||||
|
||||
for (int i = 0; i < Height; i++)
|
||||
{
|
||||
for (int j = 0; j < Width; j++)
|
||||
{
|
||||
for (int ch = 0; ch < Channel; ch++)
|
||||
{
|
||||
const size_t IndexSrc = i * someimg.step1() + j * Channel + ch;
|
||||
const size_t IndexDst = (ch * Height + i) * Width + j;
|
||||
fptr[IndexDst] = uptr[IndexSrc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(input_blob->count() == input_block_plane_size * processNum);
|
||||
|
||||
// 計算
|
||||
auto out = mNet->Forward();
|
||||
|
||||
auto b = out[0];
|
||||
|
||||
assert(b->count() == output_block_plane_size * processNum);
|
||||
|
||||
const float *ptr = nullptr;
|
||||
|
||||
if (caffe::Caffe::mode() == caffe::Caffe::CPU)
|
||||
ptr = b->cpu_data();
|
||||
else
|
||||
ptr = b->gpu_data();
|
||||
|
||||
caffe::caffe_copy(output_block_plane_size * processNum, ptr, outputBlockBuf);
|
||||
|
||||
for (int n = 0; n < processNum; n++)
|
||||
{
|
||||
const int wn = (num + n) % WidthNum;
|
||||
const int hn = (num + n) / WidthNum;
|
||||
|
||||
const int w = wn * output_crop_block_width;
|
||||
const int h = hn * output_crop_block_height;
|
||||
|
||||
const float *fptr = outputBlockBuf + (output_block_plane_size * n);
|
||||
|
||||
const auto Line = outim.step1();
|
||||
|
||||
// 結果を出力画像にコピー
|
||||
if (outim.channels() == 1)
|
||||
{
|
||||
for (int i = 0; i < output_crop_block_height; i++)
|
||||
memcpy(imptr + (h + i) * Line + w, fptr + (i + output_crop_h) * output_block_width + output_crop_w, output_crop_block_width * sizeof(float));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto LinePixel = Line / outim.channels();
|
||||
const auto Channel = outim.channels();
|
||||
|
||||
for (int i = 0; i < output_crop_block_height; i++)
|
||||
{
|
||||
for (int j = 0; j < output_crop_block_width; j++)
|
||||
{
|
||||
for (int ch = 0; ch < Channel; ch++)
|
||||
{
|
||||
const size_t IndexSrc = (ch * output_block_height + i + output_crop_h) * output_block_width + j + output_crop_w;
|
||||
const size_t IndexDst = ((h + i) * LinePixel + (w + j)) * Channel + ch;
|
||||
|
||||
imptr[IndexDst] = fptr[IndexSrc];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//{
|
||||
// cv::Mat testim(output_block_size, output_block_size, CV_32FC1);
|
||||
// float *p = (float *)testim.data;
|
||||
// for (int i = 0; i < output_block_size; i++)
|
||||
// {
|
||||
// for (int j = 0; j < output_block_size; j++)
|
||||
// {
|
||||
// p[testim.step1() * i + j] = fptr[i * output_block_size + j];
|
||||
// }
|
||||
// }
|
||||
|
||||
// const int cv_depth = DepthBitToCVDepth(8);
|
||||
// const double max_val = GetValumeMaxFromCVDepth(cv_depth);
|
||||
// const double eps = GetEPS(cv_depth);
|
||||
|
||||
// cv::Mat write_iamge;
|
||||
// testim.convertTo(write_iamge, cv_depth, max_val, eps);
|
||||
|
||||
// cv::imwrite("ti.png", write_iamge);
|
||||
// testim.release();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedProcessCaffe;
|
||||
}
|
||||
|
||||
// 値を0~1にクリッピング
|
||||
cv::threshold(outim, outim, 1.0, 1.0, cv::THRESH_TRUNC);
|
||||
cv::threshold(outim, outim, 0.0, 0.0, cv::THRESH_TOZERO);
|
||||
|
||||
outMat = outim;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
std::string cNet::GetModelName(const boost::filesystem::path &info_path)
|
||||
{
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
stInfo info;
|
||||
ret = GetInfo(info_path, info);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return std::string();
|
||||
|
||||
return info.name;
|
||||
}
|
63
common/cNet.h
Normal file
63
common/cNet.h
Normal file
@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "waifu2x.h"
|
||||
|
||||
|
||||
struct stInfo
|
||||
{
|
||||
struct stParam
|
||||
{
|
||||
int scale_factor;
|
||||
int offset;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::string arch_name;
|
||||
bool has_noise_scale;
|
||||
int channels;
|
||||
|
||||
stParam noise;
|
||||
stParam scale;
|
||||
stParam noise_scale;
|
||||
};
|
||||
|
||||
class cNet
|
||||
{
|
||||
private:
|
||||
Waifu2x::eWaifu2xModelType mMode;
|
||||
|
||||
boost::shared_ptr<caffe::Net<float>> mNet;
|
||||
|
||||
int mModelScale; // モデルが対象とする拡大率
|
||||
int mInnerScale; // ネット内部で拡大される倍率
|
||||
int mNetOffset; // ネットに入力するとどれくらい削れるか
|
||||
int mInputPlane; // ネットへの入力チャンネル数
|
||||
bool mHasNoiseScaleModel;
|
||||
|
||||
private:
|
||||
void LoadParamFromInfo(const Waifu2x::eWaifu2xModelType mode, const stInfo &info);
|
||||
Waifu2x::eWaifu2xError LoadParameterFromJson(const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path
|
||||
, const boost::filesystem::path &modelbin_path, const boost::filesystem::path &caffemodel_path, const std::string &process);
|
||||
Waifu2x::eWaifu2xError SetParameter(caffe::NetParameter ¶m, const std::string &process) const;
|
||||
|
||||
public:
|
||||
cNet();
|
||||
~cNet();
|
||||
|
||||
static Waifu2x::eWaifu2xError GetInfo(const boost::filesystem::path &info_path, stInfo &info);
|
||||
|
||||
Waifu2x::eWaifu2xError ConstractNet(const Waifu2x::eWaifu2xModelType mode, const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path, const stInfo &info, const std::string &process);
|
||||
|
||||
int GetInputPlane() const;
|
||||
int GetInnerScale() const;
|
||||
int GetNetOffset() const;
|
||||
int GetScale() const;
|
||||
|
||||
int GetInputMemorySize(const int crop_w, const int crop_h, const int outer_padding, const int batch_size) const;
|
||||
int GetOutputMemorySize(const int crop_w, const int crop_h, const int outer_padding, const int batch_size) const;
|
||||
|
||||
Waifu2x::eWaifu2xError ReconstructImage(const bool UseTTA, const int crop_w, const int crop_h, const int outer_padding, const int batch_size, float *outputBlockBuf, const cv::Mat &inMat, cv::Mat &outMat);
|
||||
|
||||
static std::string GetModelName(const boost::filesystem::path &info_path);
|
||||
};
|
895
common/stImage.cpp
Normal file
895
common/stImage.cpp
Normal file
@ -0,0 +1,895 @@
|
||||
#include "stImage.h"
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb_image.h>
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb_image_write.h>
|
||||
|
||||
const int YToRGBConvertMode = CV_GRAY2RGB;
|
||||
const int YToRGBConverInversetMode = CV_RGB2GRAY;
|
||||
const int BGRToYConvertMode = CV_BGR2YUV;
|
||||
const int BGRToConvertInverseMode = CV_YUV2BGR;
|
||||
|
||||
// floatな画像をuint8_tな画像に変換する際の四捨五入に使う値
|
||||
// https://github.com/nagadomi/waifu2x/commit/797b45ae23665a1c5e3c481c018e48e6f0d0e383
|
||||
const double clip_eps8 = (1.0 / 255.0) * 0.5 - (1.0e-7 * (1.0 / 255.0) * 0.5);
|
||||
const double clip_eps16 = (1.0 / 65535.0) * 0.5 - (1.0e-7 * (1.0 / 65535.0) * 0.5);
|
||||
const double clip_eps32 = 1.0 * 0.5 - (1.0e-7 * 0.5);
|
||||
|
||||
const std::vector<stImage::stOutputExtentionElement> stImage::OutputExtentionList =
|
||||
{
|
||||
{L".png",{8, 16}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".bmp",{8}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".jpg",{8}, 0, 100, 95, cv::IMWRITE_JPEG_QUALITY},
|
||||
{L".jp2",{8, 16}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".sr",{8}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".tif",{8, 16, 32}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".hdr",{8, 16, 32}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".exr",{8, 16, 32}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".ppm",{8, 16}, boost::optional<int>(), boost::optional<int>(), boost::optional<int>(), boost::optional<int>()},
|
||||
{L".webp",{8}, 1, 100, 100, cv::IMWRITE_WEBP_QUALITY},
|
||||
{L".tga",{8}, 0, 1, 0, 0},
|
||||
};
|
||||
|
||||
|
||||
template<typename BufType>
|
||||
static bool readFile(boost::iostreams::stream<boost::iostreams::file_descriptor_source> &is, std::vector<BufType> &buf)
|
||||
{
|
||||
if (!is)
|
||||
return false;
|
||||
|
||||
const auto size = is.seekg(0, std::ios::end).tellg();
|
||||
is.seekg(0, std::ios::beg);
|
||||
|
||||
buf.resize((size / sizeof(BufType)) + (size % sizeof(BufType)));
|
||||
is.read(buf.data(), size);
|
||||
if (is.gcount() != size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename BufType>
|
||||
static bool readFile(const boost::filesystem::path &path, std::vector<BufType> &buf)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor_source> is;
|
||||
|
||||
try
|
||||
{
|
||||
is.open(path, std::ios_base::in | std::ios_base::binary);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return readFile(is, buf);
|
||||
}
|
||||
|
||||
template<typename BufType>
|
||||
static bool writeFile(boost::iostreams::stream<boost::iostreams::file_descriptor> &os, const std::vector<BufType> &buf)
|
||||
{
|
||||
if (!os)
|
||||
return false;
|
||||
|
||||
const auto WriteSize = sizeof(BufType) * buf.size();
|
||||
os.write((const char *)buf.data(), WriteSize);
|
||||
if (os.fail())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename BufType>
|
||||
static bool writeFile(const boost::filesystem::path &path, std::vector<BufType> &buf)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor> os;
|
||||
|
||||
try
|
||||
{
|
||||
os.open(path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return writeFile(os, buf);
|
||||
}
|
||||
|
||||
static void Waifu2x_stbi_write_func(void *context, void *data, int size)
|
||||
{
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor> *osp = (boost::iostreams::stream<boost::iostreams::file_descriptor> *)context;
|
||||
osp->write((const char *)data, size);
|
||||
}
|
||||
|
||||
int stImage::DepthBitToCVDepth(const int depth_bit)
|
||||
{
|
||||
switch (depth_bit)
|
||||
{
|
||||
case 8:
|
||||
return CV_8U;
|
||||
|
||||
case 16:
|
||||
return CV_16U;
|
||||
|
||||
case 32:
|
||||
return CV_32F;
|
||||
}
|
||||
|
||||
// 不明だけどとりあえずCV_8Uを返しておく
|
||||
return CV_8U;
|
||||
}
|
||||
|
||||
double stImage::GetValumeMaxFromCVDepth(const int cv_depth)
|
||||
{
|
||||
switch (cv_depth)
|
||||
{
|
||||
case CV_8U:
|
||||
return 255.0;
|
||||
|
||||
case CV_16U:
|
||||
return 65535.0;
|
||||
|
||||
case CV_32F:
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
// 不明だけどとりあえず255.0を返しておく
|
||||
return 255.0;
|
||||
}
|
||||
|
||||
double stImage::GetEPS(const int cv_depth)
|
||||
{
|
||||
switch (cv_depth)
|
||||
{
|
||||
case CV_8U:
|
||||
return clip_eps8;
|
||||
|
||||
case CV_16U:
|
||||
return clip_eps16;
|
||||
|
||||
case CV_32F:
|
||||
return clip_eps32;
|
||||
}
|
||||
|
||||
// 不明だけどとりあえずclip_eps8返しておく
|
||||
return clip_eps8;
|
||||
}
|
||||
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::AlphaMakeBorder(std::vector<cv::Mat> &planes, const cv::Mat &alpha, const int offset)
|
||||
{
|
||||
// このカーネルと画像の畳込みを行うと、(x, y)を中心とした3×3領域の合計値が求まる
|
||||
const static cv::Mat sum2d_kernel = (cv::Mat_<double>(3, 3) <<
|
||||
1., 1., 1.,
|
||||
1., 1., 1.,
|
||||
1., 1., 1.);
|
||||
|
||||
cv::Mat mask;
|
||||
cv::threshold(alpha, mask, 0.0, 1.0, cv::THRESH_BINARY); // アルファチャンネルを二値化してマスクとして扱う
|
||||
|
||||
cv::Mat mask_nega;
|
||||
cv::threshold(mask, mask_nega, 0.0, 1.0, cv::THRESH_BINARY_INV); // 反転したマスク(値が1の箇所は完全透明でない有効な画素となる)
|
||||
|
||||
for (auto &p : planes) // 完全に透明なピクセルにあるゴミを取る
|
||||
{
|
||||
p = p.mul(mask);
|
||||
}
|
||||
|
||||
for (int i = 0; i < offset; i++)
|
||||
{
|
||||
cv::Mat mask_weight;
|
||||
cv::filter2D(mask, mask_weight, -1, sum2d_kernel, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT); // マスクの3×3領域の合計値を求める
|
||||
|
||||
cv::Mat mask_nega_u8;
|
||||
mask_nega.convertTo(mask_nega_u8, CV_8U, 255.0, clip_eps8); // mask_negaのCV_U8版(OpenCVのAPI上必要になる)
|
||||
|
||||
for (auto &p : planes) // 1チャンネルずつ処理
|
||||
{
|
||||
// チャンネルの3×3領域内の有効画素の平均値を求める
|
||||
cv::Mat border;
|
||||
cv::filter2D(p, border, -1, sum2d_kernel, cv::Point(-1, -1), 0, cv::BORDER_DEFAULT);
|
||||
border /= mask_weight;
|
||||
|
||||
// チャンネルの有効な画素の部分に、計算した平均値をコピー
|
||||
border.copyTo(p, mask_nega_u8);
|
||||
}
|
||||
|
||||
// マスクを1回膨張させたものを新しいマスクとする(マスクの3×3領域の合計値を求めたものの非0領域は、マスクを1回膨張させたものの領域に等しい)
|
||||
cv::threshold(mask_weight, mask, 0.0, 1.0, cv::THRESH_BINARY);
|
||||
// 新しいマスクの反転したマスクを計算
|
||||
cv::threshold(mask, mask_nega, 0.0, 1.0, cv::THRESH_BINARY_INV);
|
||||
}
|
||||
|
||||
// 画素を0から1にクリッピング
|
||||
for (auto &p : planes)
|
||||
{
|
||||
cv::threshold(p, p, 1.0, 1.0, cv::THRESH_TRUNC);
|
||||
cv::threshold(p, p, 0.0, 0.0, cv::THRESH_TOZERO);
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
// 画像を読み込んで値を0.0f~1.0fの範囲に変換
|
||||
Waifu2x::eWaifu2xError stImage::LoadMat(cv::Mat &im, const boost::filesystem::path &input_file)
|
||||
{
|
||||
cv::Mat original_image;
|
||||
|
||||
{
|
||||
std::vector<char> img_data;
|
||||
if (!readFile(input_file, img_data))
|
||||
return Waifu2x::eWaifu2xError_FailedOpenInputFile;
|
||||
|
||||
cv::Mat im(img_data.size(), 1, CV_8U, img_data.data());
|
||||
original_image = cv::imdecode(im, cv::IMREAD_UNCHANGED);
|
||||
|
||||
if (original_image.empty())
|
||||
{
|
||||
const Waifu2x::eWaifu2xError ret = LoadMatBySTBI(original_image, img_data);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
im = original_image;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::LoadMatBySTBI(cv::Mat &im, const std::vector<char> &img_data)
|
||||
{
|
||||
int x, y, comp;
|
||||
stbi_uc *data = stbi_load_from_memory((const stbi_uc *)img_data.data(), img_data.size(), &x, &y, &comp, 0);
|
||||
if (!data)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenInputFile;
|
||||
|
||||
int type = 0;
|
||||
switch (comp)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
case 4:
|
||||
type = CV_MAKETYPE(CV_8U, comp);
|
||||
break;
|
||||
|
||||
default:
|
||||
return Waifu2x::eWaifu2xError_FailedOpenInputFile;
|
||||
}
|
||||
|
||||
im = cv::Mat(cv::Size(x, y), type);
|
||||
|
||||
const auto LinePixel = im.step1() / im.channels();
|
||||
const auto Channel = im.channels();
|
||||
const auto Width = im.size().width;
|
||||
const auto Height = im.size().height;
|
||||
|
||||
assert(x == Width);
|
||||
assert(y == Height);
|
||||
assert(Channel == comp);
|
||||
|
||||
auto ptr = im.data;
|
||||
for (int i = 0; i < y; i++)
|
||||
{
|
||||
for (int j = 0; j < x; j++)
|
||||
{
|
||||
for (int ch = 0; ch < Channel; ch++)
|
||||
ptr[(i * LinePixel + j) * comp + ch] = data[(i * x + j) * comp + ch];
|
||||
}
|
||||
}
|
||||
|
||||
stbi_image_free(data);
|
||||
|
||||
if (comp >= 3)
|
||||
{
|
||||
// RGBだからBGRに変換
|
||||
for (int i = 0; i < y; i++)
|
||||
{
|
||||
for (int j = 0; j < x; j++)
|
||||
std::swap(ptr[(i * LinePixel + j) * comp + 0], ptr[(i * LinePixel + j) * comp + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
cv::Mat stImage::ConvertToFloat(const cv::Mat &im)
|
||||
{
|
||||
cv::Mat convert;
|
||||
switch (im.depth())
|
||||
{
|
||||
case CV_8U:
|
||||
im.convertTo(convert, CV_32F, 1.0 / GetValumeMaxFromCVDepth(CV_8U));
|
||||
break;
|
||||
|
||||
case CV_16U:
|
||||
im.convertTo(convert, CV_32F, 1.0 / GetValumeMaxFromCVDepth(CV_16U));
|
||||
break;
|
||||
|
||||
case CV_32F:
|
||||
convert = im; // 元から0.0~1.0のはずなので変換は必要ない
|
||||
break;
|
||||
}
|
||||
|
||||
return convert;
|
||||
}
|
||||
|
||||
|
||||
stImage::stImage() : mIsRequestDenoise(false), pad_w1(0), pad_h1(0), pad_w2(0), pad_h2(0)
|
||||
{
|
||||
}
|
||||
|
||||
stImage::~stImage()
|
||||
{
|
||||
}
|
||||
|
||||
void stImage::Clear()
|
||||
{
|
||||
mOrgFloatImage.release();
|
||||
mTmpImageRGB.release();
|
||||
mTmpImageA.release();
|
||||
mEndImage.release();
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::Load(const boost::filesystem::path &input_file)
|
||||
{
|
||||
Clear();
|
||||
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
cv::Mat im;
|
||||
ret = LoadMat(im, input_file);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return ret;
|
||||
|
||||
mOrgFloatImage = im;
|
||||
mOrgChannel = im.channels();
|
||||
mOrgSize = im.size();
|
||||
|
||||
const boost::filesystem::path ip(input_file);
|
||||
const boost::filesystem::path ipext(ip.extension());
|
||||
|
||||
const bool isJpeg = boost::iequals(ipext.string(), ".jpg") || boost::iequals(ipext.string(), ".jpeg");
|
||||
|
||||
mIsRequestDenoise = isJpeg;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::Load(const void* source, const int width, const int height, const int channel, const int stride)
|
||||
{
|
||||
cv::Mat original_image(cv::Size(width, height), CV_MAKETYPE(CV_8U, channel), (void *)source, stride);
|
||||
|
||||
if (original_image.channels() >= 3) // RGBなのでBGRにする
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(original_image, planes);
|
||||
|
||||
std::swap(planes[0], planes[2]);
|
||||
|
||||
cv::merge(planes, original_image);
|
||||
}
|
||||
|
||||
mOrgFloatImage = original_image;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
double stImage::GetScaleFromWidth(const int width) const
|
||||
{
|
||||
return (double)width / (double)mOrgSize.width;
|
||||
}
|
||||
|
||||
double stImage::GetScaleFromHeight(const int height) const
|
||||
{
|
||||
return (double)height / (double)mOrgSize.height;
|
||||
}
|
||||
|
||||
bool stImage::RequestDenoise() const
|
||||
{
|
||||
return mIsRequestDenoise;
|
||||
}
|
||||
|
||||
void stImage::Preprocess(const int input_plane, const int net_offset)
|
||||
{
|
||||
mOrgFloatImage = ConvertToFloat(mOrgFloatImage);
|
||||
|
||||
ConvertToNetFormat(input_plane, net_offset);
|
||||
}
|
||||
|
||||
void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset)
|
||||
{
|
||||
if (input_plane == 1) // Yモデル
|
||||
{
|
||||
if (mOrgFloatImage.channels() == 1) // 1chだけなのでそのまま
|
||||
mTmpImageRGB = mOrgFloatImage;
|
||||
else // BGRなので変換
|
||||
{
|
||||
mTmpImageRGB = mOrgFloatImage;
|
||||
|
||||
if (mTmpImageRGB.channels() == 4) // BGRAなのでAだけ取り出す
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(mTmpImageRGB, planes);
|
||||
|
||||
mTmpImageA = planes[3];
|
||||
planes.resize(3);
|
||||
|
||||
AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる
|
||||
|
||||
// CreateBrightnessImage()でBGRからYに変換するので特にRGBに変えたりはしない
|
||||
cv::merge(planes, mTmpImageRGB);
|
||||
}
|
||||
|
||||
CreateBrightnessImage(mTmpImageRGB, mTmpImageRGB);
|
||||
}
|
||||
}
|
||||
else // RGBモデル
|
||||
{
|
||||
if (mOrgFloatImage.channels() == 1) // 1chだけなのでRGBに変換
|
||||
{
|
||||
cv::cvtColor(mOrgFloatImage, mTmpImageRGB, YToRGBConvertMode);
|
||||
mOrgFloatImage.release();
|
||||
}
|
||||
else // BGRからRGBに変換(AがあったらAも取り出す)
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(mOrgFloatImage, planes);
|
||||
mOrgFloatImage.release();
|
||||
|
||||
if (planes.size() == 4) // BGRAなのでAだけ取り出す
|
||||
{
|
||||
mTmpImageA = planes[3];
|
||||
planes.resize(3);
|
||||
|
||||
AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる
|
||||
|
||||
// α拡大用にRGBに変換
|
||||
cv::cvtColor(mTmpImageA, mTmpImageA, CV_GRAY2RGB);
|
||||
}
|
||||
|
||||
// BGRからRGBにする
|
||||
std::swap(planes[0], planes[2]);
|
||||
|
||||
cv::merge(planes, mTmpImageRGB);
|
||||
}
|
||||
|
||||
mOrgFloatImage.release();
|
||||
}
|
||||
}
|
||||
|
||||
// 画像から輝度の画像を取り出す
|
||||
Waifu2x::eWaifu2xError stImage::CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
|
||||
{
|
||||
if (float_image.channels() > 1)
|
||||
{
|
||||
cv::Mat converted_color;
|
||||
cv::cvtColor(float_image, converted_color, BGRToYConvertMode);
|
||||
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(converted_color, planes);
|
||||
|
||||
im = planes[0];
|
||||
planes.clear();
|
||||
}
|
||||
else
|
||||
im = float_image;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
bool stImage::HasAlpha() const
|
||||
{
|
||||
return !mTmpImageA.empty();
|
||||
}
|
||||
|
||||
void stImage::GetScalePaddingedRGB(cv::Mat &im, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale)
|
||||
{
|
||||
GetScalePaddingedImage(mTmpImageRGB, im, size, net_offset, outer_padding, crop_w, crop_h, scale);
|
||||
}
|
||||
|
||||
void stImage::SetReconstructedRGB(cv::Mat &im, const cv::Size_<int> &size, const int inner_scale)
|
||||
{
|
||||
SetReconstructedImage(mTmpImageRGB, im, size, inner_scale);
|
||||
}
|
||||
|
||||
void stImage::GetScalePaddingedA(cv::Mat &im, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale)
|
||||
{
|
||||
GetScalePaddingedImage(mTmpImageA, im, size, net_offset, outer_padding, crop_w, crop_h, scale);
|
||||
}
|
||||
|
||||
void stImage::SetReconstructedA(cv::Mat &im, const cv::Size_<int> &size, const int inner_scale)
|
||||
{
|
||||
SetReconstructedImage(mTmpImageA, im, size, inner_scale);
|
||||
}
|
||||
|
||||
void stImage::GetScalePaddingedImage(cv::Mat &in, cv::Mat &out, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale)
|
||||
{
|
||||
cv::Mat ret;
|
||||
|
||||
if (scale > 1)
|
||||
{
|
||||
cv::Size_<int> zoom_size = in.size();
|
||||
zoom_size.width *= scale;
|
||||
zoom_size.height *= scale;
|
||||
|
||||
cv::resize(in, ret, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
|
||||
}
|
||||
else
|
||||
ret = in;
|
||||
|
||||
in.release();
|
||||
|
||||
size = ret.size();
|
||||
|
||||
PaddingImage(ret, net_offset, outer_padding, crop_w, crop_h, ret);
|
||||
|
||||
out = ret;
|
||||
}
|
||||
|
||||
// 入力画像の(Photoshopでいう)キャンバスサイズをoutput_sizeの倍数に変更
|
||||
// 画像は左上配置、余白はcv::BORDER_REPLICATEで埋める
|
||||
void stImage::PaddingImage(const cv::Mat &input, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, cv::Mat &output)
|
||||
{
|
||||
const auto pad_w1 = net_offset + outer_padding;
|
||||
const auto pad_h1 = net_offset + outer_padding;
|
||||
const auto pad_w2 = (int)ceil((double)input.size().width / (double)crop_w) * crop_w - input.size().width + net_offset + outer_padding;
|
||||
const auto pad_h2 = (int)ceil((double)input.size().height / (double)crop_h) * crop_h - input.size().height + net_offset + outer_padding;
|
||||
|
||||
cv::copyMakeBorder(input, output, pad_h1, pad_h2, pad_w1, pad_w2, cv::BORDER_REPLICATE);
|
||||
}
|
||||
|
||||
// 拡大、パディングされた画像を設定
|
||||
void stImage::SetReconstructedImage(cv::Mat &dst, cv::Mat &src, const cv::Size_<int> &size, const int inner_scale)
|
||||
{
|
||||
const cv::Size_<int> s(size * inner_scale);
|
||||
|
||||
// ブロックサイズ用のパディングを取り払う(outer_paddingは再構築の過程で取り除かれている)
|
||||
dst = src(cv::Rect(0, 0, s.width, s.height));
|
||||
|
||||
src.release();
|
||||
}
|
||||
|
||||
void stImage::Postprocess(const int input_plane, const double scale, const int depth)
|
||||
{
|
||||
DeconvertFromNetFormat(input_plane);
|
||||
ShrinkImage(scale);
|
||||
|
||||
// 値を0~1にクリッピング
|
||||
cv::threshold(mEndImage, mEndImage, 1.0, 1.0, cv::THRESH_TRUNC);
|
||||
cv::threshold(mEndImage, mEndImage, 0.0, 0.0, cv::THRESH_TOZERO);
|
||||
|
||||
mEndImage = DeconvertFromFloat(mEndImage, depth);
|
||||
|
||||
AlphaCleanImage(mEndImage);
|
||||
}
|
||||
|
||||
void stImage::DeconvertFromNetFormat(const int input_plane)
|
||||
{
|
||||
if (input_plane == 1) // Yモデル
|
||||
{
|
||||
if (mOrgChannel == 1) // もともと1chだけなのでそのまま
|
||||
{
|
||||
mEndImage = mTmpImageRGB;
|
||||
mTmpImageRGB.release();
|
||||
mOrgFloatImage.release();
|
||||
}
|
||||
else // もともとBGRなので既存アルゴリズムで拡大したUVに拡大したYを合体して戻す
|
||||
{
|
||||
std::vector<cv::Mat> color_planes;
|
||||
CreateZoomColorImage(mOrgFloatImage, mTmpImageRGB.size(), color_planes);
|
||||
mOrgFloatImage.release();
|
||||
|
||||
color_planes[0] = mTmpImageRGB;
|
||||
mTmpImageRGB.release();
|
||||
|
||||
cv::Mat converted_image;
|
||||
cv::merge(color_planes, converted_image);
|
||||
color_planes.clear();
|
||||
|
||||
cv::cvtColor(converted_image, mEndImage, BGRToConvertInverseMode);
|
||||
converted_image.release();
|
||||
|
||||
if (!mTmpImageA.empty()) // Aもあるので合体
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(mEndImage, planes);
|
||||
|
||||
planes.push_back(mTmpImageA);
|
||||
mTmpImageA.release();
|
||||
|
||||
cv::merge(planes, mEndImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // RGBモデル
|
||||
{
|
||||
// ここの地点でmOrgFloatImageは空
|
||||
|
||||
if (mOrgChannel == 1) // もともと1chだけなので戻す
|
||||
{
|
||||
cv::cvtColor(mTmpImageRGB, mEndImage, YToRGBConverInversetMode);
|
||||
mTmpImageRGB.release();
|
||||
}
|
||||
else // もともとBGRなのでRGBから戻す(AがあったらAも合体して戻す)
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(mTmpImageRGB, planes);
|
||||
mTmpImageRGB.release();
|
||||
|
||||
if (!mTmpImageA.empty()) // Aもあるので合体
|
||||
{
|
||||
// RGBから1chに戻す
|
||||
cv::cvtColor(mTmpImageA, mTmpImageA, CV_RGB2GRAY);
|
||||
|
||||
planes.push_back(mTmpImageA);
|
||||
mTmpImageA.release();
|
||||
}
|
||||
|
||||
// RGBからBGRにする
|
||||
std::swap(planes[0], planes[2]);
|
||||
|
||||
cv::merge(planes, mEndImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stImage::ShrinkImage(const double scale)
|
||||
{
|
||||
// TODO: scale = 1.0 でも悪影響を及ぼさないか調べる
|
||||
|
||||
const int scaleBase = 2; // TODO: モデルの拡大率によって可変できるようにする
|
||||
|
||||
const int scaleNum = ceil(log(scale) / log(scaleBase));
|
||||
const double shrinkRatio = scale >= 1.0 ? scale / std::pow(scaleBase, scaleNum) : scale;
|
||||
|
||||
const cv::Size_<int> ns(mOrgSize.width * scale, mOrgSize.height * scale);
|
||||
if (mEndImage.size().width != ns.width || mEndImage.size().height != ns.height)
|
||||
{
|
||||
int argo = cv::INTER_CUBIC;
|
||||
if (scale < 0.5)
|
||||
argo = cv::INTER_AREA;
|
||||
|
||||
cv::resize(mEndImage, mEndImage, ns, 0.0, 0.0, argo);
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat stImage::DeconvertFromFloat(const cv::Mat &im, const int depth)
|
||||
{
|
||||
const int cv_depth = DepthBitToCVDepth(depth);
|
||||
const double max_val = GetValumeMaxFromCVDepth(cv_depth);
|
||||
const double eps = GetEPS(cv_depth);
|
||||
|
||||
cv::Mat ret;
|
||||
if (depth == 32) // 出力がfloat形式なら変換しない
|
||||
ret = im;
|
||||
else
|
||||
im.convertTo(ret, cv_depth, max_val, eps);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
void AlphaZeroToZero(std::vector<cv::Mat> &planes)
|
||||
{
|
||||
cv::Mat alpha(planes[3]);
|
||||
|
||||
const T *aptr = (const T *)alpha.data;
|
||||
|
||||
T *ptr0 = (T *)planes[0].data;
|
||||
T *ptr1 = (T *)planes[1].data;
|
||||
T *ptr2 = (T *)planes[2].data;
|
||||
|
||||
const size_t Line = alpha.step1();
|
||||
const size_t Width = alpha.size().width;
|
||||
const size_t Height = alpha.size().height;
|
||||
|
||||
for (size_t i = 0; i < Height; i++)
|
||||
{
|
||||
for (size_t j = 0; j < Width; j++)
|
||||
{
|
||||
const size_t pos = Line * i + j;
|
||||
|
||||
if (aptr[pos] == (T)0)
|
||||
ptr0[pos] = ptr1[pos] = ptr2[pos] = (T)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stImage::AlphaCleanImage(cv::Mat &im)
|
||||
{
|
||||
// 完全透明のピクセルの色を消す(処理の都合上、完全透明のピクセルにも色を付けたから)
|
||||
// モデルによっては画像全域の完全透明の場所にごく小さい値のアルファが広がることがある。それを消すためにcv_depthへ変換してからこの処理を行うことにした
|
||||
// (ただしcv_depthが32の場合だと意味は無いが)
|
||||
// TODO: モデル(例えばPhoto)によっては0しかない画像を変換しても0.000114856390とかになるので、適切な値のクリッピングを行う?
|
||||
if (im.channels() > 3)
|
||||
{
|
||||
std::vector<cv::Mat> planes;
|
||||
cv::split(im, planes);
|
||||
im.release();
|
||||
|
||||
const auto depth = planes[0].depth();
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8U:
|
||||
AlphaZeroToZero<uint8_t>(planes);
|
||||
break;
|
||||
|
||||
case CV_16U:
|
||||
AlphaZeroToZero<uint16_t>(planes);
|
||||
break;
|
||||
|
||||
case CV_32F:
|
||||
AlphaZeroToZero<float>(planes);
|
||||
break;
|
||||
|
||||
case CV_64F:
|
||||
AlphaZeroToZero<double>(planes);
|
||||
break;
|
||||
}
|
||||
|
||||
cv::merge(planes, im);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
|
||||
Waifu2x::eWaifu2xError stImage::CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes)
|
||||
{
|
||||
cv::Mat zoom_cubic_image;
|
||||
cv::resize(float_image, zoom_cubic_image, zoom_size, 0.0, 0.0, cv::INTER_CUBIC);
|
||||
|
||||
cv::Mat converted_cubic_image;
|
||||
cv::cvtColor(zoom_cubic_image, converted_cubic_image, BGRToYConvertMode);
|
||||
zoom_cubic_image.release();
|
||||
|
||||
cv::split(converted_cubic_image, cubic_planes);
|
||||
converted_cubic_image.release();
|
||||
|
||||
// このY成分は使わないので解放
|
||||
cubic_planes[0].release();
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
cv::Mat stImage::GetEndImage() const
|
||||
{
|
||||
return mEndImage;
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::Save(const boost::filesystem::path &output_file, const boost::optional<int> &output_quality)
|
||||
{
|
||||
return WriteMat(mEndImage, output_file, output_quality);
|
||||
}
|
||||
|
||||
Waifu2x::eWaifu2xError stImage::WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional<int> &output_quality)
|
||||
{
|
||||
const boost::filesystem::path ip(output_file);
|
||||
const std::string ext = ip.extension().string();
|
||||
|
||||
if (boost::iequals(ext, ".tga"))
|
||||
{
|
||||
unsigned char *data = im.data;
|
||||
|
||||
std::vector<unsigned char> rgbimg;
|
||||
if (im.channels() >= 3 || im.step1() != im.size().width * im.channels()) // RGB用バッファにコピー(あるいはパディングをとる)
|
||||
{
|
||||
const auto Line = im.step1();
|
||||
const auto Channel = im.channels();
|
||||
const auto Width = im.size().width;
|
||||
const auto Height = im.size().height;
|
||||
|
||||
rgbimg.resize(Width * Height * Channel);
|
||||
|
||||
const auto Stride = Width * Channel;
|
||||
for (int i = 0; i < Height; i++)
|
||||
memcpy(rgbimg.data() + Stride * i, im.data + Line * i, Stride);
|
||||
|
||||
data = rgbimg.data();
|
||||
}
|
||||
|
||||
if (im.channels() >= 3) // BGRをRGBに並び替え
|
||||
{
|
||||
const auto Line = im.step1();
|
||||
const auto Channel = im.channels();
|
||||
const auto Width = im.size().width;
|
||||
const auto Height = im.size().height;
|
||||
|
||||
auto ptr = rgbimg.data();
|
||||
for (int i = 0; i < Height; i++)
|
||||
{
|
||||
for (int j = 0; j < Width; j++)
|
||||
std::swap(ptr[(i * Width + j) * Channel + 0], ptr[(i * Width + j) * Channel + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
boost::iostreams::stream<boost::iostreams::file_descriptor> os;
|
||||
|
||||
try
|
||||
{
|
||||
os.open(output_file, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return Waifu2x::eWaifu2xError_FailedOpenOutputFile;
|
||||
}
|
||||
|
||||
if (!os)
|
||||
return Waifu2x::eWaifu2xError_FailedOpenOutputFile;
|
||||
|
||||
// RLE圧縮の設定
|
||||
bool isSet = false;
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
for (const auto &elm : OutputExtentionList)
|
||||
{
|
||||
if (elm.ext == L".tga")
|
||||
{
|
||||
if (elm.imageQualitySettingVolume && output_quality)
|
||||
{
|
||||
stbi_write_tga_with_rle = *output_quality;
|
||||
isSet = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 設定されなかったのでデフォルトにする
|
||||
if (!isSet)
|
||||
stbi_write_tga_with_rle = 1;
|
||||
|
||||
if (!stbi_write_tga_to_func(Waifu2x_stbi_write_func, &os, im.size().width, im.size().height, im.channels(), data))
|
||||
return Waifu2x::eWaifu2xError_FailedOpenOutputFile;
|
||||
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
const boost::filesystem::path op(output_file);
|
||||
const boost::filesystem::path opext(op.extension());
|
||||
|
||||
std::vector<int> params;
|
||||
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
for (const auto &elm : OutputExtentionList)
|
||||
{
|
||||
if (elm.ext == opext)
|
||||
{
|
||||
if (elm.imageQualitySettingVolume && output_quality)
|
||||
{
|
||||
params.push_back(*elm.imageQualitySettingVolume);
|
||||
params.push_back(*output_quality);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uchar> buf;
|
||||
cv::imencode(ext, im, buf, params);
|
||||
|
||||
if (writeFile(output_file, buf))
|
||||
return Waifu2x::eWaifu2xError_OK;
|
||||
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
return Waifu2x::eWaifu2xError_FailedOpenOutputFile;
|
||||
}
|
128
common/stImage.h
Normal file
128
common/stImage.h
Normal file
@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
|
||||
#include "waifu2x.h"
|
||||
|
||||
|
||||
class stImage
|
||||
{
|
||||
private:
|
||||
cv::Mat mOrgFloatImage;
|
||||
int mOrgChannel;
|
||||
cv::Size_<int> mOrgSize;
|
||||
|
||||
bool mIsRequestDenoise;
|
||||
|
||||
cv::Mat mTmpImageRGB; // RGB(あるいはY)
|
||||
cv::Mat mTmpImageA; // αチャンネル
|
||||
|
||||
cv::Mat mEndImage; // 完成した画像
|
||||
|
||||
int pad_w1;
|
||||
int pad_h1;
|
||||
int pad_w2;
|
||||
int pad_h2;
|
||||
|
||||
public:
|
||||
struct stOutputExtentionElement
|
||||
{
|
||||
std::wstring ext;
|
||||
std::vector<int> depthList;
|
||||
boost::optional<int> imageQualityStart;
|
||||
boost::optional<int> imageQualityEnd;
|
||||
boost::optional<int> imageQualityDefault;
|
||||
boost::optional<int> imageQualitySettingVolume;
|
||||
};
|
||||
|
||||
const static std::vector<stOutputExtentionElement> OutputExtentionList;
|
||||
|
||||
private:
|
||||
static Waifu2x::eWaifu2xError LoadMatBySTBI(cv::Mat &im, const std::vector<char> &img_data);
|
||||
|
||||
static cv::Mat ConvertToFloat(const cv::Mat &im);
|
||||
|
||||
static Waifu2x::eWaifu2xError AlphaMakeBorder(std::vector<cv::Mat> &planes, const cv::Mat &alpha, const int offset);
|
||||
|
||||
static cv::Mat DeconvertFromFloat(const cv::Mat &im, const int depth);
|
||||
static void AlphaCleanImage(cv::Mat &im);
|
||||
|
||||
static Waifu2x::eWaifu2xError WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional<int> &output_quality);
|
||||
|
||||
void ConvertToNetFormat(const int input_plane, const int alpha_offset);
|
||||
|
||||
Waifu2x::eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im);
|
||||
void PaddingImage(const cv::Mat &input, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, cv::Mat &output);
|
||||
Waifu2x::eWaifu2xError CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes);
|
||||
|
||||
// 拡大、パディングされた画像を取得
|
||||
// この関数を呼び出した後、mTmpImageRGBは空になるので注意
|
||||
void GetScalePaddingedImage(cv::Mat &in, cv::Mat &out, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale);
|
||||
|
||||
// 変換された画像を設定
|
||||
// size: GetScalePaddingedImage()で取得したsize
|
||||
void SetReconstructedImage(cv::Mat &dst, cv::Mat &src, const cv::Size_<int> &size, const int inner_scale);
|
||||
|
||||
void DeconvertFromNetFormat(const int input_plane);
|
||||
void ShrinkImage(const double scale);
|
||||
|
||||
static int DepthBitToCVDepth(const int depth_bit);
|
||||
static double GetValumeMaxFromCVDepth(const int cv_depth);
|
||||
static double GetEPS(const int cv_depth);
|
||||
|
||||
public:
|
||||
stImage();
|
||||
~stImage();
|
||||
|
||||
void Clear();
|
||||
|
||||
static Waifu2x::eWaifu2xError LoadMat(cv::Mat &im, const boost::filesystem::path &input_file);
|
||||
|
||||
Waifu2x::eWaifu2xError Load(const boost::filesystem::path &input_file);
|
||||
|
||||
// source: (4チャンネルの場合は)RGBAな画素配列
|
||||
// dest: (4チャンネルの場合は)処理したRGBAな画素配列
|
||||
// width: widthの縦幅
|
||||
// height: heightの横幅
|
||||
// channel: sourceのチャンネル数
|
||||
// stride: sourceのストライド(バイト単位)
|
||||
// sourceはPostprocess()が終わるまで存在している必要がある
|
||||
Waifu2x::eWaifu2xError Load(const void* source, const int width, const int height, const int channel, const int stride);
|
||||
|
||||
double GetScaleFromWidth(const int width) const;
|
||||
double GetScaleFromHeight(const int width) const;
|
||||
|
||||
bool RequestDenoise() const;
|
||||
|
||||
// 前処理
|
||||
// RGBモデルの場合はこれが終わった時にはmOrgFloatImageが空になっているので注意
|
||||
void Preprocess(const int input_plane, const int net_offset);
|
||||
|
||||
bool HasAlpha() const;
|
||||
|
||||
// 拡大、パディングされた画像を取得
|
||||
// この関数を呼び出した後、mTmpImageRGBは空になるので注意
|
||||
void GetScalePaddingedRGB(cv::Mat &im, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale);
|
||||
|
||||
// 変換された画像を設定
|
||||
// この関数を呼び出した後、imは空になるので注意
|
||||
// size: GetScalePaddingedImage()で取得したsize
|
||||
void SetReconstructedRGB(cv::Mat &im, const cv::Size_<int> &size, const int inner_scale);
|
||||
|
||||
// 拡大、パディングされた画像を取得
|
||||
// この関数を呼び出した後、mTmpImageAは空になるので注意
|
||||
void GetScalePaddingedA(cv::Mat &im, cv::Size_<int> &size, const int net_offset, const int outer_padding,
|
||||
const int crop_w, const int crop_h, const int scale);
|
||||
|
||||
// 拡大された画像を設定
|
||||
// この関数を呼び出した後、imは空になるので注意
|
||||
// size: GetScalePaddingedImage()で取得したsize
|
||||
void SetReconstructedA(cv::Mat &im, const cv::Size_<int> &size, const int inner_scale);
|
||||
|
||||
void Postprocess(const int input_plane, const double scale, const int depth);
|
||||
|
||||
cv::Mat GetEndImage() const;
|
||||
|
||||
Waifu2x::eWaifu2xError Save(const boost::filesystem::path &output_file, const boost::optional<int> &output_quality);
|
||||
};
|
2219
common/waifu2x.cpp
2219
common/waifu2x.cpp
File diff suppressed because it is too large
Load Diff
142
common/waifu2x.h
142
common/waifu2x.h
@ -21,9 +21,21 @@ namespace caffe
|
||||
class NetParameter;
|
||||
};
|
||||
|
||||
class cNet;
|
||||
class stImage;
|
||||
|
||||
|
||||
class Waifu2x
|
||||
{
|
||||
public:
|
||||
enum eWaifu2xModelType
|
||||
{
|
||||
eWaifu2xModelTypeNoise,
|
||||
eWaifu2xModelTypeScale,
|
||||
eWaifu2xModelTypeNoiseScale,
|
||||
eWaifu2xModelTypeAutoScale,
|
||||
};
|
||||
|
||||
enum eWaifu2xError
|
||||
{
|
||||
eWaifu2xError_OK = 0,
|
||||
@ -59,126 +71,78 @@ public:
|
||||
|
||||
typedef std::function<bool()> waifu2xCancelFunc;
|
||||
|
||||
struct stOutputExtentionElement
|
||||
{
|
||||
std::wstring ext;
|
||||
std::vector<int> depthList;
|
||||
boost::optional<int> imageQualityStart;
|
||||
boost::optional<int> imageQualityEnd;
|
||||
boost::optional<int> imageQualityDefault;
|
||||
boost::optional<int> imageQualitySettingVolume;
|
||||
};
|
||||
|
||||
const static std::vector<stOutputExtentionElement> OutputExtentionList;
|
||||
static std::string ExeDir;
|
||||
|
||||
private:
|
||||
bool is_inited;
|
||||
bool mIsInited;
|
||||
|
||||
// 一度に処理する画像の幅
|
||||
int crop_size;
|
||||
// 一度に何ブロック分処理するか
|
||||
int batch_size;
|
||||
eWaifu2xModelType mMode;
|
||||
int mNoiseLevel;
|
||||
std::string mProcess;
|
||||
int mGPUNo;
|
||||
|
||||
// ネットに入力する画像のサイズ
|
||||
int input_block_size;
|
||||
// ブロック変換後の出力サイズ
|
||||
int output_size;
|
||||
// ネットワークに入力する画像のサイズ(出力画像の幅はlayer_num * 2だけ小さくなる)
|
||||
int block_width_height;
|
||||
// srcnn.prototxtで定義された入力する画像のサイズ
|
||||
int original_width_height;
|
||||
bool mIsCuda;
|
||||
|
||||
std::string mode;
|
||||
int noise_level;
|
||||
boost::optional<double> scale_ratio;
|
||||
boost::optional<int> scale_width;
|
||||
boost::optional<int> scale_height;
|
||||
boost::filesystem::path model_dir;
|
||||
std::string process;
|
||||
std::shared_ptr<cNet> mNoiseNet;
|
||||
std::shared_ptr<cNet> mScaleNet;
|
||||
|
||||
int inner_padding;
|
||||
int outer_padding;
|
||||
int mInputPlane; // ネットへの入力チャンネル数
|
||||
int mMaxNetOffset; // ネットに入力するとどれくらい削れるか
|
||||
bool mHasNoiseScale;
|
||||
|
||||
int output_block_size;
|
||||
|
||||
int input_plane;
|
||||
|
||||
bool isCuda;
|
||||
|
||||
boost::shared_ptr<caffe::Net<float>> net_noise;
|
||||
boost::shared_ptr<caffe::Net<float>> net_scale;
|
||||
|
||||
float *input_block;
|
||||
float *dummy_data;
|
||||
float *output_block;
|
||||
|
||||
bool use_tta;
|
||||
|
||||
boost::optional<int> output_quality;
|
||||
int output_depth;
|
||||
|
||||
int gpu_no;
|
||||
float *mOutputBlock;
|
||||
size_t mOutputBlockSize;
|
||||
|
||||
private:
|
||||
static eWaifu2xError LoadMat(cv::Mat &float_image, const boost::filesystem::path &input_file);
|
||||
static eWaifu2xError LoadMatBySTBI(cv::Mat &float_image, const std::vector<char> &img_data);
|
||||
static eWaifu2xError AlphaMakeBorder(std::vector<cv::Mat> &planes, const cv::Mat &alpha, const int offset);
|
||||
eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im);
|
||||
eWaifu2xError PaddingImage(const cv::Mat &input, cv::Mat &output);
|
||||
eWaifu2xError Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::Size_<int> &zoom_size);
|
||||
eWaifu2xError CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes);
|
||||
eWaifu2xError ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path, const std::string &process);
|
||||
eWaifu2xError LoadParameterFromJson(boost::shared_ptr<caffe::Net<float>> &net, const boost::filesystem::path &model_path, const boost::filesystem::path ¶m_path
|
||||
, const boost::filesystem::path &modelbin_path, const boost::filesystem::path &caffemodel_path, const std::string &process);
|
||||
eWaifu2xError SetParameter(caffe::NetParameter ¶m, const std::string &process) const;
|
||||
eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im);
|
||||
static eWaifu2xError WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional<int> &output_quality);
|
||||
static boost::filesystem::path GetModeDirPath(const boost::filesystem::path &model_dir);
|
||||
static boost::filesystem::path GetInfoPath(const boost::filesystem::path &model_dir);
|
||||
|
||||
eWaifu2xError BeforeReconstructFloatMatProcess(const cv::Mat &in, cv::Mat &out, bool &convertBGRflag);
|
||||
eWaifu2xError ReconstructFloatMat(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
||||
eWaifu2xError Reconstruct(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
||||
eWaifu2xError AfterReconstructFloatMatProcess(const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &floatim, cv::Mat &in, cv::Mat &out);
|
||||
static double CalcScaleRatio(const boost::optional<double> scale_ratio, const boost::optional<int> scale_width, const boost::optional<int> scale_height,
|
||||
const stImage &image);
|
||||
|
||||
eWaifu2xError waifu2xConvetedMat(const bool isJpeg, const cv::Mat &inMat, cv::Mat &outMat,
|
||||
const waifu2xCancelFunc cancel_func = nullptr);
|
||||
|
||||
double CalcScaleRatio(const cv::Size_<int> &size) const;
|
||||
|
||||
static int DepthBitToCVDepth(const int depth_bit);
|
||||
static double GetValumeMaxFromCVDepth(const int cv_depth);
|
||||
static double GetEPS(const int cv_depth);
|
||||
Waifu2x::eWaifu2xError ReconstructImage(const double factor, const int crop_w, const int crop_h, const bool use_tta, const int batch_size,
|
||||
const bool isReconstructNoise, const bool isReconstructScale, const Waifu2x::waifu2xCancelFunc cancel_func, stImage &image);
|
||||
Waifu2x::eWaifu2xError ReconstructScale(const int crop_w, const int crop_h, const bool use_tta, const int batch_size,
|
||||
const Waifu2x::waifu2xCancelFunc cancel_func, stImage &image);
|
||||
Waifu2x::eWaifu2xError ReconstructNoiseScale(const int crop_w, const int crop_h, const bool use_tta, const int batch_size,
|
||||
const Waifu2x::waifu2xCancelFunc cancel_func, stImage &image);
|
||||
Waifu2x::eWaifu2xError ReconstructByNet(std::shared_ptr<cNet> net, const int crop_w, const int crop_h, const bool use_tta, const int batch_size,
|
||||
const Waifu2x::waifu2xCancelFunc cancel_func, cv::Mat &im);
|
||||
Waifu2x::eWaifu2xError ProcessNet(std::shared_ptr<cNet> net, const int crop_w, const int crop_h, const bool use_tta, const int batch_size, cv::Mat &im);
|
||||
|
||||
public:
|
||||
Waifu2x();
|
||||
~Waifu2x();
|
||||
|
||||
static eWaifu2xcuDNNError can_use_cuDNN();
|
||||
static eWaifu2xCudaError can_use_CUDA();
|
||||
static eWaifu2xcuDNNError can_use_cuDNN();
|
||||
|
||||
static void init_liblary();
|
||||
static void init_liblary(int argc, char** argv);
|
||||
static void quit_liblary();
|
||||
|
||||
// mode: noise or scale or noise_scale or auto_scale
|
||||
// process: cpu or gpu or cudnn
|
||||
eWaifu2xError init(int argc, char** argv, const std::string &mode, const int noise_level,
|
||||
const boost::optional<double> scale_ratio, const boost::optional<int> scale_width, const boost::optional<int> scale_height,
|
||||
const boost::filesystem::path &model_dir, const std::string &process,
|
||||
const boost::optional<int> output_quality = boost::optional<int>(), const int output_depth = 8, const bool use_tta = false,
|
||||
const int crop_size = 128, const int batch_size = 1, const int gpu_no = 0);
|
||||
|
||||
void destroy();
|
||||
eWaifu2xError Init(const eWaifu2xModelType mode, const int noise_level,
|
||||
const boost::filesystem::path &model_dir, const std::string &process, const int gpu_no = 0);
|
||||
|
||||
eWaifu2xError waifu2x(const boost::filesystem::path &input_file, const boost::filesystem::path &output_file,
|
||||
const waifu2xCancelFunc cancel_func = nullptr);
|
||||
const boost::optional<double> scale_ratio, const boost::optional<int> scale_width, const boost::optional<int> scale_height,
|
||||
const waifu2xCancelFunc cancel_func = nullptr, const int crop_w = 128, const int crop_h = 128,
|
||||
const boost::optional<int> output_quality = boost::optional<int>(), const int output_depth = 8, const bool use_tta = false,
|
||||
const int batch_size = 1);
|
||||
|
||||
// factor: 倍率
|
||||
// source: (4チャンネルの場合は)RGBAな画素配列
|
||||
// dest: (4チャンネルの場合は)処理したRGBAな画素配列
|
||||
// in_stride: sourceのストライド(バイト単位)
|
||||
// out_stride: destのストライド(バイト単位)
|
||||
eWaifu2xError waifu2x(double factor, const void* source, void* dest, int width, int height, int in_channel, int in_stride, int out_channel, int out_stride);
|
||||
eWaifu2xError waifu2x(const double factor, const void* source, void* dest, const int width, const int height,
|
||||
const int in_channel, const int in_stride, const int out_channel, const int out_stride,
|
||||
const int crop_w = 128, const int crop_h = 128, const bool use_tta = false, const int batch_size = 1);
|
||||
|
||||
void Destroy();
|
||||
|
||||
const std::string& used_process() const;
|
||||
|
||||
static cv::Mat LoadMat(const boost::filesystem::path &path);
|
||||
static std::string GetModelName(const boost::filesystem::path &model_dir);
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <codecvt>
|
||||
#include <cblas.h>
|
||||
#include <dlgs.h>
|
||||
#include <boost/tokenizer.hpp>
|
||||
@ -14,6 +15,7 @@
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include "../common/waifu2x.h"
|
||||
#include "../common/stImage.h"
|
||||
#include "CDialog.h"
|
||||
#include "CControl.h"
|
||||
//#include <boost/program_options.hpp>
|
||||
@ -116,42 +118,50 @@ namespace
|
||||
|
||||
tstring DialogEvent::AddName() const
|
||||
{
|
||||
tstring addstr;
|
||||
tstring addstr(TEXT("("));
|
||||
|
||||
const std::string ModelName = Waifu2x::GetModelName(model_dir);
|
||||
|
||||
#ifdef UNICODE
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> cv;
|
||||
const std::wstring wModelName = cv.from_bytes(ModelName);
|
||||
|
||||
addstr += wModelName;
|
||||
}
|
||||
#else
|
||||
addstr += ModelName;
|
||||
#endif
|
||||
|
||||
addstr += TEXT(")");
|
||||
|
||||
addstr += TEXT("(");
|
||||
switch (modelType)
|
||||
switch (mode)
|
||||
{
|
||||
case eModelTypeRGB:
|
||||
addstr += TEXT("RGB");
|
||||
case Waifu2x::eWaifu2xModelTypeNoise:
|
||||
addstr += TEXT("noise");
|
||||
break;
|
||||
|
||||
case eModelTypePhoto:
|
||||
addstr += TEXT("Photo");
|
||||
case Waifu2x::eWaifu2xModelTypeScale:
|
||||
addstr += TEXT("scale");
|
||||
break;
|
||||
|
||||
case eModelTypeY:
|
||||
addstr += TEXT("Y");
|
||||
case Waifu2x::eWaifu2xModelTypeNoiseScale:
|
||||
addstr += TEXT("noise_scale");
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeAutoScale:
|
||||
addstr += TEXT("auto_scale");
|
||||
break;
|
||||
}
|
||||
addstr += TEXT(")");
|
||||
|
||||
addstr += TEXT("(");
|
||||
if (mode == "noise")
|
||||
addstr += TEXT("noise");
|
||||
else if (mode == "scale")
|
||||
addstr += TEXT("scale");
|
||||
else if (mode == "noise_scale")
|
||||
addstr += TEXT("noise_scale");
|
||||
else if (mode == "auto_scale")
|
||||
addstr += TEXT("auto_scale");
|
||||
addstr += TEXT(")");
|
||||
|
||||
if (mode.find("noise") != mode.npos || mode.find("auto_scale") != mode.npos)
|
||||
if (mode == Waifu2x::eWaifu2xModelTypeNoise || mode == Waifu2x::eWaifu2xModelTypeNoiseScale || mode == Waifu2x::eWaifu2xModelTypeAutoScale)
|
||||
addstr += TEXT("(Level") + to_tstring(noise_level) + TEXT(")");
|
||||
if (use_tta)
|
||||
addstr += TEXT("(tta)");
|
||||
|
||||
if (mode.find("scale") != mode.npos)
|
||||
if (mode == Waifu2x::eWaifu2xModelTypeScale || mode == Waifu2x::eWaifu2xModelTypeNoiseScale || mode == Waifu2x::eWaifu2xModelTypeAutoScale)
|
||||
{
|
||||
if (scaleType == eScaleTypeRatio)
|
||||
addstr += TEXT("(x") + to_tstring(scale_ratio) + TEXT(")");
|
||||
@ -189,13 +199,25 @@ bool DialogEvent::SyncMember(const bool NotSyncCropSize, const bool silent)
|
||||
}
|
||||
|
||||
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE), BM_GETCHECK, 0, 0))
|
||||
mode = "noise";
|
||||
{
|
||||
mode = Waifu2x::eWaifu2xModelTypeNoise;
|
||||
modeStr = "noise";
|
||||
}
|
||||
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_SCALE), BM_GETCHECK, 0, 0))
|
||||
mode = "scale";
|
||||
{
|
||||
mode = Waifu2x::eWaifu2xModelTypeScale;
|
||||
modeStr = "scale";
|
||||
}
|
||||
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODE_NOISE_SCALE), BM_GETCHECK, 0, 0))
|
||||
mode = "noise_scale";
|
||||
{
|
||||
mode = Waifu2x::eWaifu2xModelTypeNoiseScale;
|
||||
modeStr = "noise_scale";
|
||||
}
|
||||
else
|
||||
mode = "auto_scale";
|
||||
{
|
||||
mode = Waifu2x::eWaifu2xModelTypeAutoScale;
|
||||
modeStr = "auto_scale";
|
||||
}
|
||||
|
||||
if (SendMessage(GetDlgItem(dh, IDC_RADIONOISE_LEVEL1), BM_GETCHECK, 0, 0))
|
||||
noise_level = 1;
|
||||
@ -274,24 +296,37 @@ bool DialogEvent::SyncMember(const bool NotSyncCropSize, const bool silent)
|
||||
scale_height = l;
|
||||
}
|
||||
|
||||
if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODEL_RGB), BM_GETCHECK, 0, 0))
|
||||
{
|
||||
const int cur = SendMessage(GetDlgItem(dh, IDC_COMBO_MODEL), CB_GETCURSEL, 0, 0);
|
||||
switch (cur)
|
||||
{
|
||||
case 0:
|
||||
model_dir = TEXT("models/anime_style_art_rgb");
|
||||
modelType = eModelTypeRGB;
|
||||
}
|
||||
else if (SendMessage(GetDlgItem(dh, IDC_RADIO_MODEL_Y), BM_GETCHECK, 0, 0))
|
||||
{
|
||||
model_dir = TEXT("models/anime_style_art");
|
||||
modelType = eModelTypeY;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case 1:
|
||||
model_dir = TEXT("models/photo");
|
||||
modelType = eModelTypePhoto;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
model_dir = TEXT("models/upconv_7_anime_style_art_rgb");
|
||||
modelType = eModelTypeUpConvRGB;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
model_dir = TEXT("models/anime_style_art");
|
||||
modelType = eModelTypeY;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const auto &OutputExtentionList = Waifu2x::OutputExtentionList;
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
|
||||
const int cur = SendMessage(GetDlgItem(dh, IDC_COMBO_OUT_EXT), CB_GETCURSEL, 0, 0);
|
||||
if (cur < 0 || cur >= OutputExtentionList.size())
|
||||
@ -383,8 +418,9 @@ void DialogEvent::SetCropSizeList(const boost::filesystem::path & input_path)
|
||||
int gcd = 1;
|
||||
if (boost::filesystem::exists(input_path) && !boost::filesystem::is_directory(input_path))
|
||||
{
|
||||
auto mat = Waifu2x::LoadMat(input_path.string());
|
||||
if (mat.empty())
|
||||
cv::Mat mat;
|
||||
const auto ret = stImage::LoadMat(mat, input_path.string());
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
return;
|
||||
|
||||
auto size = mat.size();
|
||||
@ -670,10 +706,21 @@ void DialogEvent::ProcessWaifu2x()
|
||||
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
boost::optional<double> ScaleRatio;
|
||||
boost::optional<int> ScaleWidth;
|
||||
boost::optional<int> ScaleHeight;
|
||||
Waifu2x w;
|
||||
ret = w.Init(mode, noise_level, model_dir, process, gpu_no);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, 0);
|
||||
else
|
||||
{
|
||||
const auto InitEndTime = std::chrono::system_clock::now();
|
||||
|
||||
const int maxFile = file_paths.size();
|
||||
int num = 0;
|
||||
|
||||
ProgessFunc(maxFile, 0);
|
||||
|
||||
boost::optional<double> ScaleRatio;
|
||||
boost::optional<int> ScaleWidth, ScaleHeight;
|
||||
switch (scaleType)
|
||||
{
|
||||
case eScaleTypeRatio:
|
||||
@ -687,19 +734,6 @@ void DialogEvent::ProcessWaifu2x()
|
||||
break;
|
||||
}
|
||||
|
||||
Waifu2x w;
|
||||
ret = w.init(__argc, __argv, mode, noise_level, ScaleRatio, ScaleWidth, ScaleHeight, model_dir, process, output_quality, output_depth, use_tta, crop_size, batch_size, gpu_no);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, 0);
|
||||
else
|
||||
{
|
||||
const auto InitEndTime = std::chrono::system_clock::now();
|
||||
|
||||
const int maxFile = file_paths.size();
|
||||
int num = 0;
|
||||
|
||||
ProgessFunc(maxFile, 0);
|
||||
|
||||
DWORD startTime = 0;
|
||||
|
||||
int64_t processeNum = 0;
|
||||
@ -719,10 +753,10 @@ void DialogEvent::ProcessWaifu2x()
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = w.waifu2x(p.first, p.second, [this]()
|
||||
ret = w.waifu2x(p.first, p.second, ScaleRatio, ScaleWidth, ScaleHeight, [this]()
|
||||
{
|
||||
return cancelFlag;
|
||||
});
|
||||
}, crop_size, crop_size, output_quality, output_depth, use_tta, batch_size);
|
||||
|
||||
num++;
|
||||
ProgessFunc(maxFile, num);
|
||||
@ -894,14 +928,24 @@ void DialogEvent::SaveIni(const bool isSyncMember)
|
||||
else
|
||||
tScaleHeight = TEXT("");
|
||||
|
||||
if (mode == ("noise"))
|
||||
switch (mode)
|
||||
{
|
||||
case Waifu2x::eWaifu2xModelTypeNoise:
|
||||
tmode = TEXT("noise");
|
||||
else if (mode == ("scale"))
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeScale:
|
||||
tmode = TEXT("scale");
|
||||
else if (mode == ("auto_scale"))
|
||||
tmode = TEXT("auto_scale");
|
||||
else // noise_scale
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeNoiseScale:
|
||||
tmode = TEXT("noise_scale");
|
||||
break;
|
||||
|
||||
case Waifu2x::eWaifu2xModelTypeAutoScale:
|
||||
tmode = TEXT("auto_scale");
|
||||
break;
|
||||
}
|
||||
|
||||
if (process == "gpu")
|
||||
tprcess = TEXT("gpu");
|
||||
@ -1143,7 +1187,7 @@ UINT_PTR DialogEvent::OFNHookProcOut(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARA
|
||||
return 0L;
|
||||
}
|
||||
|
||||
DialogEvent::DialogEvent() : dh(nullptr), mode("noise_scale"), noise_level(1), scale_ratio(2.0), scale_width(0), scale_height(0), model_dir(TEXT("models/anime_style_art_rgb")),
|
||||
DialogEvent::DialogEvent() : dh(nullptr), mode(Waifu2x::eWaifu2xModelTypeNoiseScale), modeStr("noise_scale"), noise_level(1), scale_ratio(2.0), scale_width(0), scale_height(0), model_dir(TEXT("models/anime_style_art_rgb")),
|
||||
process("gpu"), outputExt(TEXT(".png")), inputFileExt(TEXT("png:jpg:jpeg:tif:tiff:bmp:tga")),
|
||||
use_tta(false), output_depth(8), crop_size(128), batch_size(1), gpu_no(0), isLastError(false), scaleType(eScaleTypeEnd),
|
||||
TimeLeftThread(-1), TimeLeftGetTimeThread(0), isCommandLineStart(false), tAutoMode(TEXT("none")),
|
||||
@ -1398,9 +1442,6 @@ void DialogEvent::SetWindowTextLang()
|
||||
SET_WINDOW_TEXT(IDC_RADIO_SCALE_WIDTH);
|
||||
SET_WINDOW_TEXT(IDC_RADIO_SCALE_HEIGHT);
|
||||
SET_WINDOW_TEXT(IDC_STATIC_MODEL);
|
||||
SET_WINDOW_TEXT(IDC_RADIO_MODEL_RGB);
|
||||
SET_WINDOW_TEXT(IDC_RADIO_MODEL_PHOTO);
|
||||
SET_WINDOW_TEXT(IDC_RADIO_MODEL_Y);
|
||||
SET_WINDOW_TEXT(IDC_CHECK_TTA);
|
||||
SET_WINDOW_TEXT(IDC_STATIC_PROCESS_SPEED_SETTING);
|
||||
SET_WINDOW_TEXT(IDC_STATIC_CROP_SIZE);
|
||||
@ -1416,6 +1457,21 @@ void DialogEvent::SetWindowTextLang()
|
||||
SET_WINDOW_TEXT(IDC_BUTTON_CLEAR_OUTPUT_DIR);
|
||||
|
||||
#undef SET_WINDOW_TEXT
|
||||
|
||||
const int cur = SendMessage(GetDlgItem(dh, IDC_COMBO_MODEL), CB_GETCURSEL, 0, 0);
|
||||
|
||||
HWND hwndCombo = GetDlgItem(dh, IDC_COMBO_MODEL);
|
||||
while (SendMessage(hwndCombo, CB_GETCOUNT, 0, 0) != 0)
|
||||
{
|
||||
SendMessage(hwndCombo, CB_DELETESTRING, 0, 0);
|
||||
}
|
||||
|
||||
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)langStringList.GetString(L"IDC_RADIO_MODEL_RGB").c_str());
|
||||
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)langStringList.GetString(L"IDC_RADIO_MODEL_PHOTO").c_str());
|
||||
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)langStringList.GetString(L"IDC_RADIO_MODEL_UPCONV_RGB").c_str());
|
||||
SendMessage(hwndCombo, CB_ADDSTRING, 0, (LPARAM)langStringList.GetString(L"IDC_RADIO_MODEL_Y").c_str());
|
||||
|
||||
SendMessage(GetDlgItem(dh, IDC_COMBO_MODEL), CB_SETCURSEL, cur, 0);
|
||||
}
|
||||
|
||||
void DialogEvent::SetDepthAndQuality(const bool SetDefaultQuality)
|
||||
@ -1427,7 +1483,7 @@ void DialogEvent::SetDepthAndQuality(const bool SetDefaultQuality)
|
||||
if (cur < 0)
|
||||
return;
|
||||
|
||||
const auto &OutputExtentionList = Waifu2x::OutputExtentionList;
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
if (cur >= OutputExtentionList.size())
|
||||
return;
|
||||
|
||||
@ -1569,7 +1625,7 @@ void DialogEvent::Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
{
|
||||
HWND houtext = GetDlgItem(dh, IDC_COMBO_OUT_EXT);
|
||||
|
||||
const auto &OutputExtentionList = Waifu2x::OutputExtentionList;
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
for (const auto &elm : OutputExtentionList)
|
||||
{
|
||||
SendMessageW(houtext, CB_ADDSTRING, 0, (LPARAM)elm.ext.c_str());
|
||||
@ -1797,24 +1853,18 @@ void DialogEvent::Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIONOISE_LEVEL3), BM_SETCHECK, BST_CHECKED, 0);
|
||||
}
|
||||
|
||||
|
||||
int index = 0;
|
||||
if (modelType == eModelTypeRGB)
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
}
|
||||
index = 0;
|
||||
else if (modelType == eModelTypePhoto)
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
}
|
||||
index = 1;
|
||||
else if (modelType == eModelTypeUpConvRGB)
|
||||
index = 2;
|
||||
else
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_CHECKED, 0);
|
||||
}
|
||||
index = 3;
|
||||
|
||||
SendMessage(GetDlgItem(dh, IDC_COMBO_MODEL), CB_SETCURSEL, index, 0);
|
||||
|
||||
if (use_tta)
|
||||
SendMessage(GetDlgItem(hWnd, IDC_CHECK_TTA), BM_SETCHECK, BST_CHECKED, 0);
|
||||
@ -1839,7 +1889,7 @@ void DialogEvent::Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
HWND houtext = GetDlgItem(dh, IDC_COMBO_OUT_EXT);
|
||||
|
||||
size_t defaultIndex = 0;
|
||||
const auto &OutputExtentionList = Waifu2x::OutputExtentionList;
|
||||
const auto &OutputExtentionList = stImage::OutputExtentionList;
|
||||
for (size_t i = 0; i < OutputExtentionList.size(); i++)
|
||||
{
|
||||
const auto &elm = OutputExtentionList[i];
|
||||
@ -1966,6 +2016,7 @@ void DialogEvent::Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
cmdModelTypeConstraintV.push_back(L"anime_style_art_rgb");
|
||||
cmdModelTypeConstraintV.push_back(L"photo");
|
||||
cmdModelTypeConstraintV.push_back(L"anime_style_art_y");
|
||||
cmdModelTypeConstraintV.push_back(L"upconv_7_anime_style_art_rgb");
|
||||
TCLAP::ValuesConstraint<std::wstring> cmdModelTypeConstraint(cmdModelTypeConstraintV);
|
||||
TCLAP::ValueArg<std::wstring> cmdModelType(L"y", L"model_type", L"model type",
|
||||
false, L"anime_style_art_rgb", &cmdModelTypeConstraint, cmd);
|
||||
@ -2185,24 +2236,17 @@ void DialogEvent::Create(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
|
||||
if (cmdModelType.isSet())
|
||||
{
|
||||
int index = 0;
|
||||
if (cmdModelType.getValue() == L"anime_style_art_rgb")
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
}
|
||||
index = 0;
|
||||
else if (cmdModelType.getValue() == L"photo")
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_CHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
}
|
||||
index = 1;
|
||||
else if (cmdModelType.getValue() == L"anime_style_art_y")
|
||||
index = 2;
|
||||
else
|
||||
{
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_RGB), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_PHOTO), BM_SETCHECK, BST_UNCHECKED, 0);
|
||||
SendMessage(GetDlgItem(hWnd, IDC_RADIO_MODEL_Y), BM_SETCHECK, BST_CHECKED, 0);
|
||||
}
|
||||
index = 3;
|
||||
|
||||
SendMessage(GetDlgItem(dh, IDC_COMBO_MODEL), CB_SETCURSEL, index, 0);
|
||||
|
||||
isSetParam = true;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <atomic>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include "../common/waifu2x.h"
|
||||
#include "resource.h"
|
||||
#include "tstring.h"
|
||||
#include "LangStringList.h"
|
||||
@ -33,7 +34,8 @@ private:
|
||||
tstring input_str;
|
||||
std::vector<tstring> input_str_multi;
|
||||
tstring output_str;
|
||||
std::string mode;
|
||||
std::string modeStr;
|
||||
Waifu2x::eWaifu2xModelType mode;
|
||||
int noise_level;
|
||||
double scale_ratio;
|
||||
int scale_width;
|
||||
@ -85,6 +87,7 @@ private:
|
||||
eModelTypeRGB,
|
||||
eModelTypePhoto,
|
||||
eModelTypeY,
|
||||
eModelTypeUpConvRGB,
|
||||
eModelTypeEnd,
|
||||
};
|
||||
|
||||
|
Binary file not shown.
@ -13,7 +13,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
||||
LPSTR lpCmdLine,
|
||||
int nCmdShow)
|
||||
{
|
||||
Waifu2x::init_liblary();
|
||||
Waifu2x::init_liblary(__argc, __argv);
|
||||
|
||||
// 管理者権限で起動してもファイルのドロップを受け付けるようにする
|
||||
ChangeWindowMessageFilter(WM_DROPFILES, MSGFLT_ADD);
|
||||
@ -75,9 +75,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL1);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL2);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIONOISE_LEVEL3);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIO_MODEL_RGB);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIO_MODEL_PHOTO);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_RADIO_MODEL_Y);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_COMBO_MODEL);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_CHECK_TTA);
|
||||
cDialog.SetCommandCallBack(SetClassFunc(DialogEvent::UpdateAddString, &cDialogEvent), NULL, IDC_COMBO_OUTPUT_DEPTH);
|
||||
|
||||
|
Binary file not shown.
@ -95,6 +95,8 @@
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\common\cNet.cpp" />
|
||||
<ClCompile Include="..\common\stImage.cpp" />
|
||||
<ClCompile Include="..\common\waifu2x.cpp" />
|
||||
<ClCompile Include="CControl.cpp" />
|
||||
<ClCompile Include="CDialog.cpp" />
|
||||
@ -103,6 +105,8 @@
|
||||
<ClCompile Include="Source.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\cNet.h" />
|
||||
<ClInclude Include="..\common\stImage.h" />
|
||||
<ClInclude Include="..\common\waifu2x.h" />
|
||||
<ClInclude Include="CControl.h" />
|
||||
<ClInclude Include="CDialog.h" />
|
||||
|
@ -13,14 +13,14 @@
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="common">
|
||||
<UniqueIdentifier>{8f85ea70-f834-4cfc-8869-629e95423258}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Source.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\waifu2x.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CControl.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
@ -33,11 +33,17 @@
|
||||
<ClCompile Include="MainDialog.cpp">
|
||||
<Filter>ソース ファイル</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\cNet.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\stImage.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\common\waifu2x.cpp">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\common\waifu2x.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CControl.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
@ -71,6 +77,15 @@
|
||||
<ClInclude Include="MainDialog.h">
|
||||
<Filter>ヘッダー ファイル</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\cNet.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\stImage.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\common\waifu2x.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc">
|
||||
|
Loading…
x
Reference in New Issue
Block a user