forked from nagadomi/waifu2x
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 1273b36
Showing
19 changed files
with
7,313 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
*~ | ||
cache/*.png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
<html> | ||
<head> | ||
<style type="text/css" rel="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css"></style> | ||
<style type="text/css"> | ||
body { | ||
margin: 1em 2em 1em 2em; | ||
background: LightGray; | ||
width: 640px; | ||
} | ||
fieldset { | ||
margin-top: 1em; | ||
margin-bottom: 1em; | ||
} | ||
.about { | ||
font-size: 0.8em; | ||
margin: 1em 0 1em 0; | ||
} | ||
.help { | ||
font-size: 0.8em; | ||
margin: 1em 0 1em 0; | ||
} | ||
</style> | ||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | ||
<script type="text/javascript"> | ||
function clear_file() { | ||
var new_file = $("#file").clone(); | ||
new_file.change(clear_url); | ||
$("#file").replaceWith(new_file); | ||
} | ||
function clear_url() { | ||
$("#url").val("") | ||
} | ||
$(function (){ | ||
$("#url").change(clear_file); | ||
$("#file").change(clear_url); | ||
}) | ||
</script> | ||
</head> | ||
<body> | ||
<h1>waifu2x</h1> | ||
<div class="header"> | ||
<a href="https://github.com/you"> | ||
<img style="position: absolute; top: 0; left: 540; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"> | ||
</a> | ||
<a href="index.ja.html">ja</a>/<a href="index.html">en</a> | ||
</div> | ||
<div class="about"> | ||
Single-Image Super-Resolution for anime/fan-arts using Deep Convolutional Neural Networks. | ||
</div> | ||
<form action="/api" method="POST" enctype="multipart/form-data" target="_blank"> | ||
<fieldset> | ||
<legend>Image</legend> | ||
<div> | ||
URL: <input id="url" type="text" name="url" size="64"/> or | ||
</div> | ||
<div> | ||
FILE: <input id="file" type="file" name="file"/> | ||
</div> | ||
<div class="help"> | ||
Limits: FileSize: 2MB, Noise Reduction: 2560x2560px, Upscaling: 1280x1280px | ||
</div> | ||
</fieldset> | ||
<fieldset> | ||
<legend>Noise Reduction (expect JPEG Artifact)</legend> | ||
<label><input type="radio" name="noise" value="0"> None</label> | ||
<label><input type="radio" name="noise" value="1" checked="checked"> Low</label> | ||
<label><input type="radio" name="noise" value="2"> High</label> | ||
</fieldset> | ||
<fieldset> | ||
<legend>Upscaling</legend> | ||
<label><input type="radio" name="scale" value="0" checked="checked"> None</label> | ||
<label><input type="radio" name="scale" value="1"> 1.6x</label> | ||
<label><input type="radio" name="scale" value="2"> 2x</label> | ||
</fieldset> | ||
<input type="submit"/> | ||
</form> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<html lang="ja"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<style type="text/css" rel="http://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.min.css"></style> | ||
<style type="text/css"> | ||
body { | ||
margin: 1em 2em 1em 2em; | ||
background: LightGray; | ||
width: 640px; | ||
} | ||
fieldset { | ||
margin-top: 1em; | ||
margin-bottom: 1em; | ||
} | ||
.about { | ||
font-size: 0.8em; | ||
margin: 1em 0 1em 0; | ||
} | ||
.help { | ||
font-size: 0.8em; | ||
margin: 1em 0 1em 0; | ||
} | ||
</style> | ||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> | ||
<script type="text/javascript"> | ||
function clear_file() { | ||
var new_file = $("#file").clone(); | ||
new_file.change(clear_url); | ||
$("#file").replaceWith(new_file); | ||
} | ||
function clear_url() { | ||
$("#url").val("") | ||
} | ||
$(function (){ | ||
$("#url").change(clear_file); | ||
$("#file").change(clear_url); | ||
}) | ||
</script> | ||
</head> | ||
<body> | ||
<h1>waifu2x</h1> | ||
<div class="header"> | ||
<a href="https://github.com/you"> | ||
<img style="position: absolute; top: 0; left: 540; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"> | ||
</a> | ||
</div> | ||
<div class="about"> | ||
深層畳み込みニューラルネットワークによる二次元画像のための超解像システム. | ||
</div> | ||
<form action="/api" method="POST" enctype="multipart/form-data" target="_blank"> | ||
<fieldset> | ||
<legend>Image</legend> | ||
<div> | ||
URL: <input id="url" type="text" name="url" size="64"/> or | ||
</div> | ||
<div> | ||
FILE: <input id="file" type="file" name="file"/> | ||
</div> | ||
<div class="help"> | ||
制限: サイズ: 2MB, ノイズ除去: 2560x2560px, 拡大: 1280x1280px | ||
</div> | ||
</fieldset> | ||
<fieldset> | ||
<legend>ノイズ除去 (JPEGノイズを想定)</legend> | ||
<label><input type="radio" name="noise" value="0"> なし</label> | ||
<label><input type="radio" name="noise" value="1" checked="checked"> 弱</label> | ||
<label><input type="radio" name="noise" value="2"> 強</label> | ||
</fieldset> | ||
<fieldset> | ||
<legend>拡大</legend> | ||
<label><input type="radio" name="scale" value="0" checked="checked"> なし</label> | ||
<label><input type="radio" name="scale" value="1"> 1.6x</label> | ||
<label><input type="radio" name="scale" value="2"> 2x</label> | ||
</fieldset> | ||
<input type="submit" value="実行"/> | ||
</form> | ||
<div class="help"> | ||
<ul> | ||
<li>なし/なしで入力画像を変換せずに出力する。ブラウザのタブで変換結果を比較したい人用。</li> | ||
<li>JPEG画像であれば劣化がないように見えてもノイズ除去弱を推奨。</li> | ||
<li>マンガスキャンの拡大はスクリーントーンが謎の模様に再構成されるため非対応。</li> | ||
</ul> | ||
</div> | ||
</body> | ||
</html> |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
require 'cunn' | ||
require 'cudnn' | ||
require './lib/LeakyReLU' | ||
|
||
torch.setdefaulttensortype("torch.FloatTensor") | ||
|
||
-- ref: https://github.com/torch/nn/issues/112#issuecomment-64427049 | ||
local function zeroDataSize(data) | ||
if type(data) == 'table' then | ||
for i = 1, #data do | ||
data[i] = zeroDataSize(data[i]) | ||
end | ||
elseif type(data) == 'userdata' then | ||
data = torch.Tensor():typeAs(data) | ||
end | ||
return data | ||
end | ||
|
||
-- Resize the output, gradInput, etc temporary tensors to zero (so that the | ||
-- on disk size is smaller) | ||
local function cleanupModel(node) | ||
if node.output ~= nil then | ||
node.output = zeroDataSize(node.output) | ||
end | ||
if node.gradInput ~= nil then | ||
node.gradInput = zeroDataSize(node.gradInput) | ||
end | ||
if node.finput ~= nil then | ||
node.finput = zeroDataSize(node.finput) | ||
end | ||
if tostring(node) == "nn.LeakyReLU" then | ||
if node.negative ~= nil then | ||
node.negative = zeroDataSize(node.negative) | ||
end | ||
end | ||
if tostring(node) == "nn.Dropout" then | ||
if node.noise ~= nil then | ||
node.noise = zeroDataSize(node.noise) | ||
end | ||
end | ||
-- Recurse on nodes with 'modules' | ||
if (node.modules ~= nil) then | ||
if (type(node.modules) == 'table') then | ||
for i = 1, #node.modules do | ||
local child = node.modules[i] | ||
cleanupModel(child) | ||
end | ||
end | ||
end | ||
|
||
collectgarbage() | ||
end | ||
|
||
local cmd = torch.CmdLine() | ||
cmd:text() | ||
cmd:text("cleanup model") | ||
cmd:text("Options:") | ||
cmd:option("-model", "./model.t7", 'path of model file') | ||
cmd:option("-iformat", "binary", 'input format') | ||
cmd:option("-oformat", "binary", 'output format') | ||
|
||
local opt = cmd:parse(arg) | ||
local model = torch.load(opt.model, opt.iformat) | ||
if model then | ||
cleanupModel(model) | ||
torch.save(opt.model, model, opt.oformat) | ||
else | ||
error("model not found") | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
if nn.LeakyReLU then | ||
return | ||
end | ||
local LeakyReLU, parent = torch.class('nn.LeakyReLU','nn.Module') | ||
|
||
function LeakyReLU:__init(negative_scale) | ||
parent.__init(self) | ||
self.negative_scale = negative_scale or 0.333 | ||
self.negative = torch.Tensor() | ||
end | ||
|
||
function LeakyReLU:updateOutput(input) | ||
self.output:resizeAs(input):copy(input):abs():add(input):div(2) | ||
self.negative:resizeAs(input):copy(input):abs():add(-1.0, input):mul(-0.5*self.negative_scale) | ||
self.output:add(self.negative) | ||
|
||
return self.output | ||
end | ||
|
||
function LeakyReLU:updateGradInput(input, gradOutput) | ||
self.gradInput:resizeAs(gradOutput) | ||
-- filter positive | ||
self.negative:sign():add(1) | ||
torch.cmul(self.gradInput, gradOutput, self.negative) | ||
-- filter negative | ||
self.negative:add(-1):mul(-1 * self.negative_scale):cmul(gradOutput) | ||
self.gradInput:add(self.negative) | ||
|
||
return self.gradInput | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
local gm = require 'graphicsmagick' | ||
require 'pl' | ||
|
||
local image_loader = {} | ||
|
||
function image_loader.decode_float(blob) | ||
local im = image_loader.decode_byte(blob) | ||
if im then | ||
im = im:float():div(255) | ||
end | ||
return im | ||
end | ||
function image_loader.encode_png(tensor) | ||
local im = gm.Image(tensor, "RGB", "DHW") | ||
im:format("png") | ||
return im:toBlob() | ||
end | ||
function image_loader.decode_byte(blob) | ||
local load_image = function() | ||
local im = gm.Image() | ||
im:fromBlob(blob, #blob) | ||
-- FIXME: How to detect that a image has an alpha channel? | ||
if blob:sub(1, 4) == "\x89PNG" or blob:sub(1, 3) == "GIF" then | ||
-- merge alpha channel | ||
im = im:toTensor('float', 'RGBA', 'DHW') | ||
local w2 = im[4] | ||
local w1 = im[4] * -1 + 1 | ||
local new_im = torch.FloatTensor(3, im:size(2), im:size(3)) | ||
-- apply the white background | ||
new_im[1]:copy(im[1]):cmul(w2):add(w1) | ||
new_im[2]:copy(im[2]):cmul(w2):add(w1) | ||
new_im[3]:copy(im[3]):cmul(w2):add(w1) | ||
im = new_im:mul(255):byte() | ||
else | ||
im = im:toTensor('byte', 'RGB', 'DHW') | ||
end | ||
return im | ||
end | ||
local state, ret = pcall(load_image) | ||
if state then | ||
return ret | ||
else | ||
return nil | ||
end | ||
end | ||
function image_loader.load_float(file) | ||
local fp = io.open(file, "rb") | ||
local buff = fp:read("*a") | ||
fp:close() | ||
return image_loader.decode_float(buff) | ||
end | ||
function image_loader.load_byte(file) | ||
local fp = io.open(file, "rb") | ||
local buff = fp:read("*a") | ||
fp:close() | ||
return image_loader.decode_byte(buff) | ||
end | ||
local function test() | ||
require 'image' | ||
local img | ||
img = image_loader.load_float("./a.jpg") | ||
if img then | ||
print(img:min()) | ||
print(img:max()) | ||
image.display(img) | ||
end | ||
img = image_loader.load_float("./b.png") | ||
if img then | ||
image.display(img) | ||
end | ||
end | ||
--test() | ||
return image_loader |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
local gm = require 'graphicsmagick' | ||
local image = require 'image' | ||
local iproc = {} | ||
|
||
function iproc.sample(src, width, height) | ||
local t = "float" | ||
if src:type() == "torch.ByteTensor" then | ||
t = "byte" | ||
end | ||
local im = gm.Image(src, "RGB", "DHW") | ||
im:sample(math.ceil(width), math.ceil(height)) | ||
return im:toTensor(t, "RGB", "DHW") | ||
end | ||
function iproc.scale(src, width, height, filter) | ||
local t = "float" | ||
if src:type() == "torch.ByteTensor" then | ||
t = "byte" | ||
end | ||
filter = filter or "Box" | ||
local im = gm.Image(src, "RGB", "DHW") | ||
im:size(math.ceil(width), math.ceil(height), filter) | ||
return im:toTensor(t, "RGB", "DHW") | ||
end | ||
function iproc.padding(img, w1, w2, h1, h2) | ||
local dst_height = img:size(2) + h1 + h2 | ||
local dst_width = img:size(3) + w1 + w2 | ||
local flow = torch.Tensor(2, dst_height, dst_width) | ||
flow[1] = torch.ger(torch.linspace(0, dst_height -1, dst_height), torch.ones(dst_width)) | ||
flow[2] = torch.ger(torch.ones(dst_height), torch.linspace(0, dst_width - 1, dst_width)) | ||
flow[1]:add(-h1) | ||
flow[2]:add(-w1) | ||
return image.warp(img, flow, "simple", false, "clamp") | ||
end | ||
|
||
return iproc |
Oops, something went wrong.