mirror of
https://github.com/lltcggie/waifu2x-caffe.git
synced 2025-06-26 13:42:48 +00:00
全体の設計を変更
This commit is contained in:
parent
a78fbbf322
commit
a2b222ee12
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#if defined(WIN32) || defined(WIN64)
|
#if defined(WIN32) || defined(WIN64)
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#undef LoadImage
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -42,12 +44,21 @@ const auto original_width_height = 128 + layer_num * 2;
|
|||||||
const int ConvertMode = CV_RGB2YUV;
|
const int ConvertMode = CV_RGB2YUV;
|
||||||
const int ConvertInverseMode = CV_YUV2RGB;
|
const int ConvertInverseMode = CV_YUV2RGB;
|
||||||
|
|
||||||
std::once_flag waifu2x_once_flag;
|
static std::once_flag waifu2x_once_flag;
|
||||||
std::once_flag waifu2x_cudnn_once_flag;
|
static std::once_flag waifu2x_cudnn_once_flag;
|
||||||
|
|
||||||
|
|
||||||
|
Waifu2x::Waifu2x() : is_inited(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Waifu2x::~Waifu2x()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
// cuDNNが使えるかチェック。現状Windowsのみ
|
// cuDNNが使えるかチェック。現状Windowsのみ
|
||||||
bool can_use_cuDNN()
|
bool Waifu2x::can_use_cuDNN()
|
||||||
{
|
{
|
||||||
static bool cuDNNFlag = false;
|
static bool cuDNNFlag = false;
|
||||||
std::call_once(waifu2x_cudnn_once_flag, [&]()
|
std::call_once(waifu2x_cudnn_once_flag, [&]()
|
||||||
@ -80,7 +91,7 @@ bool can_use_cuDNN()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 画像を読み込んで値を0.0f~1.0fの範囲に変換
|
// 画像を読み込んで値を0.0f~1.0fの範囲に変換
|
||||||
eWaifu2xError LoadImage(cv::Mat &float_image, const std::string &input_file)
|
Waifu2x::eWaifu2xError Waifu2x::LoadImage(cv::Mat &float_image, const std::string &input_file)
|
||||||
{
|
{
|
||||||
cv::Mat original_image = cv::imread(input_file, cv::IMREAD_UNCHANGED);
|
cv::Mat original_image = cv::imread(input_file, cv::IMREAD_UNCHANGED);
|
||||||
if (original_image.empty())
|
if (original_image.empty())
|
||||||
@ -115,7 +126,7 @@ eWaifu2xError LoadImage(cv::Mat &float_image, const std::string &input_file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 画像から輝度の画像を取り出す
|
// 画像から輝度の画像を取り出す
|
||||||
eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
|
Waifu2x::eWaifu2xError Waifu2x::CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
|
||||||
{
|
{
|
||||||
cv::Mat converted_color;
|
cv::Mat converted_color;
|
||||||
cv::cvtColor(float_image, converted_color, ConvertMode);
|
cv::cvtColor(float_image, converted_color, ConvertMode);
|
||||||
@ -131,7 +142,7 @@ eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
|
|||||||
|
|
||||||
// 入力画像の(Photoshopでいう)キャンバスサイズをoutput_sizeの倍数に変更
|
// 入力画像の(Photoshopでいう)キャンバスサイズをoutput_sizeの倍数に変更
|
||||||
// 画像は左上配置、余白はcv::BORDER_REPLICATEで埋める
|
// 画像は左上配置、余白はcv::BORDER_REPLICATEで埋める
|
||||||
eWaifu2xError PaddingImage(const cv::Mat &input, cv::Mat &output)
|
Waifu2x::eWaifu2xError Waifu2x::PaddingImage(const cv::Mat &input, cv::Mat &output)
|
||||||
{
|
{
|
||||||
const auto h_blocks = (int)floor(input.size().width / output_size) + (input.size().width % output_size == 0 ? 0 : 1);
|
const auto h_blocks = (int)floor(input.size().width / output_size) + (input.size().width % output_size == 0 ? 0 : 1);
|
||||||
const auto w_blocks = (int)floor(input.size().height / output_size) + (input.size().height % output_size == 0 ? 0 : 1);
|
const auto w_blocks = (int)floor(input.size().height / output_size) + (input.size().height % output_size == 0 ? 0 : 1);
|
||||||
@ -148,7 +159,7 @@ eWaifu2xError PaddingImage(const cv::Mat &input, cv::Mat &output)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 画像をcv::INTER_NEARESTで二倍に拡大して、PaddingImage()でパディングする
|
// 画像をcv::INTER_NEARESTで二倍に拡大して、PaddingImage()でパディングする
|
||||||
eWaifu2xError Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::Size_<int> &zoom_size)
|
Waifu2x::eWaifu2xError Waifu2x::Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::Size_<int> &zoom_size)
|
||||||
{
|
{
|
||||||
zoom_size = input.size();
|
zoom_size = input.size();
|
||||||
zoom_size.width *= 2;
|
zoom_size.width *= 2;
|
||||||
@ -161,7 +172,7 @@ eWaifu2xError Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::S
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
|
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
|
||||||
eWaifu2xError CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes)
|
Waifu2x::eWaifu2xError Waifu2x::CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<int> &zoom_size, std::vector<cv::Mat> &cubic_planes)
|
||||||
{
|
{
|
||||||
cv::Mat zoom_cubic_image;
|
cv::Mat zoom_cubic_image;
|
||||||
cv::resize(float_image, zoom_cubic_image, zoom_size, 0.0, 0.0, cv::INTER_CUBIC);
|
cv::resize(float_image, zoom_cubic_image, zoom_size, 0.0, 0.0, cv::INTER_CUBIC);
|
||||||
@ -180,7 +191,7 @@ eWaifu2xError CreateZoomColorImage(const cv::Mat &float_image, const cv::Size_<i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 学習したパラメータをファイルから読み込む
|
// 学習したパラメータをファイルから読み込む
|
||||||
eWaifu2xError LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std::string ¶m_path)
|
Waifu2x::eWaifu2xError Waifu2x::LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std::string ¶m_path)
|
||||||
{
|
{
|
||||||
rapidjson::Document d;
|
rapidjson::Document d;
|
||||||
std::vector<char> jsonBuf;
|
std::vector<char> jsonBuf;
|
||||||
@ -295,7 +306,7 @@ eWaifu2xError LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std:
|
|||||||
|
|
||||||
// モデルファイルからネットワークを構築
|
// モデルファイルからネットワークを構築
|
||||||
// processでcudnnが指定されなかった場合はcuDNNが呼び出されないように変更する
|
// processでcudnnが指定されなかった場合はcuDNNが呼び出されないように変更する
|
||||||
eWaifu2xError ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const std::string &model_path, const std::string &process)
|
Waifu2x::eWaifu2xError Waifu2x::ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const std::string &model_path, const std::string &process)
|
||||||
{
|
{
|
||||||
caffe::NetParameter param;
|
caffe::NetParameter param;
|
||||||
if (!caffe::ReadProtoFromTextFile(model_path, ¶m))
|
if (!caffe::ReadProtoFromTextFile(model_path, ¶m))
|
||||||
@ -337,7 +348,7 @@ eWaifu2xError ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ネットワークを使って画像を再構築する
|
// ネットワークを使って画像を再構築する
|
||||||
eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im, const waifu2xProgressFunc func)
|
Waifu2x::eWaifu2xError Waifu2x::ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im)
|
||||||
{
|
{
|
||||||
const auto Height = im.size().height;
|
const auto Height = im.size().height;
|
||||||
const auto Width = im.size().width;
|
const auto Width = im.size().width;
|
||||||
@ -464,18 +475,21 @@ eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat
|
|||||||
return eWaifu2xError_OK;
|
return eWaifu2xError_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <boost/timer.hpp>
|
Waifu2x::eWaifu2xError Waifu2x::init(int argc, char** argv, const std::string &Mode, const int NoiseLevel, const double ScaleRatio, const std::string &ModelDir, const std::string &Process)
|
||||||
|
|
||||||
eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPair> &file_paths,
|
|
||||||
const std::string &mode, const int noise_level, const double scale_ratio, const std::string &model_dir, const std::string &process,
|
|
||||||
std::vector<PathAndErrorPair> &errors, const waifu2xCancelFunc cancel_func, const waifu2xProgressFunc progress_func, const waifu2xTimeFunc time_func)
|
|
||||||
{
|
{
|
||||||
if (scale_ratio <= 0.0)
|
Waifu2x::eWaifu2xError ret;
|
||||||
|
|
||||||
|
if (is_inited)
|
||||||
|
return eWaifu2xError_OK;
|
||||||
|
|
||||||
|
if (ScaleRatio <= 0.0)
|
||||||
return eWaifu2xError_InvalidParameter;
|
return eWaifu2xError_InvalidParameter;
|
||||||
|
|
||||||
const auto StartTime = std::chrono::system_clock::now();
|
mode = Mode;
|
||||||
|
noise_level = NoiseLevel;
|
||||||
eWaifu2xError ret;
|
scale_ratio = ScaleRatio;
|
||||||
|
model_dir = ModelDir;
|
||||||
|
process = Process;
|
||||||
|
|
||||||
std::call_once(waifu2x_once_flag, [argc, argv]()
|
std::call_once(waifu2x_once_flag, [argc, argv]()
|
||||||
{
|
{
|
||||||
@ -490,12 +504,11 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
|||||||
|
|
||||||
const auto cuDNNCheckStartTime = std::chrono::system_clock::now();
|
const auto cuDNNCheckStartTime = std::chrono::system_clock::now();
|
||||||
|
|
||||||
std::string process_fix(process);
|
if (process == "gpu")
|
||||||
if (process_fix == "gpu")
|
|
||||||
{
|
{
|
||||||
// cuDNNが使えそうならcuDNNを使う
|
// cuDNNが使えそうならcuDNNを使う
|
||||||
if (can_use_cuDNN())
|
if (can_use_cuDNN())
|
||||||
process_fix = "cudnn";
|
process = "cudnn";
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto cuDNNCheckEndTime = std::chrono::system_clock::now();
|
const auto cuDNNCheckEndTime = std::chrono::system_clock::now();
|
||||||
@ -516,20 +529,17 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
|||||||
if (!boost::filesystem::exists(mode_dir_path))
|
if (!boost::filesystem::exists(mode_dir_path))
|
||||||
return eWaifu2xError_FailedOpenModelFile;
|
return eWaifu2xError_FailedOpenModelFile;
|
||||||
|
|
||||||
if (process_fix == "cpu")
|
if (process == "cpu")
|
||||||
caffe::Caffe::set_mode(caffe::Caffe::CPU);
|
caffe::Caffe::set_mode(caffe::Caffe::CPU);
|
||||||
else
|
else
|
||||||
caffe::Caffe::set_mode(caffe::Caffe::GPU);
|
caffe::Caffe::set_mode(caffe::Caffe::GPU);
|
||||||
|
|
||||||
boost::shared_ptr<caffe::Net<float>> net_noise;
|
|
||||||
boost::shared_ptr<caffe::Net<float>> net_scale;
|
|
||||||
|
|
||||||
if (mode == "noise" || mode == "noise_scale" || mode == "auto_scale")
|
if (mode == "noise" || mode == "noise_scale" || mode == "auto_scale")
|
||||||
{
|
{
|
||||||
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
|
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
|
||||||
const std::string param_path = (mode_dir_path / ("noise" + std::to_string(noise_level) + "_model.json")).string();
|
const std::string param_path = (mode_dir_path / ("noise" + std::to_string(noise_level) + "_model.json")).string();
|
||||||
|
|
||||||
ret = ConstractNet(net_noise, model_path, process_fix);
|
ret = ConstractNet(net_noise, model_path, process);
|
||||||
if (ret != eWaifu2xError_OK)
|
if (ret != eWaifu2xError_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -543,7 +553,7 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
|||||||
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
|
const std::string model_path = (mode_dir_path / "srcnn.prototxt").string();
|
||||||
const std::string param_path = (mode_dir_path / "scale2.0x_model.json").string();
|
const std::string param_path = (mode_dir_path / "scale2.0x_model.json").string();
|
||||||
|
|
||||||
ret = ConstractNet(net_scale, model_path, process_fix);
|
ret = ConstractNet(net_scale, model_path, process);
|
||||||
if (ret != eWaifu2xError_OK)
|
if (ret != eWaifu2xError_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -552,165 +562,145 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto InitEndTime = std::chrono::system_clock::now();
|
is_inited = true;
|
||||||
|
|
||||||
int fileCount = 0;
|
return eWaifu2xError_OK;
|
||||||
for (const auto &p : file_paths)
|
}
|
||||||
|
|
||||||
|
void Waifu2x::destroy()
|
||||||
|
{
|
||||||
|
net_noise.reset();
|
||||||
|
net_scale.reset();
|
||||||
|
|
||||||
|
is_inited = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Waifu2x::eWaifu2xError Waifu2x::waifu2x(const std::string &input_file, const std::string &output_file,
|
||||||
|
const waifu2xCancelFunc cancel_func)
|
||||||
|
{
|
||||||
|
Waifu2x::eWaifu2xError ret;
|
||||||
|
|
||||||
|
if (!is_inited)
|
||||||
|
return eWaifu2xError_NotInitialized;
|
||||||
|
|
||||||
|
cv::Mat float_image;
|
||||||
|
ret = LoadImage(float_image, input_file);
|
||||||
|
if (ret != eWaifu2xError_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
cv::Mat im;
|
||||||
|
CreateBrightnessImage(float_image, im);
|
||||||
|
|
||||||
|
cv::Size_<int> image_size = 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");
|
||||||
|
|
||||||
|
const bool isReconstructNoise = mode == "noise" || mode == "noise_scale" || (mode == "auto_scale" && isJpeg);
|
||||||
|
const bool isReconstructScale = mode == "scale" || mode == "noise_scale";
|
||||||
|
|
||||||
|
if (isReconstructNoise)
|
||||||
{
|
{
|
||||||
if (progress_func)
|
PaddingImage(im, im);
|
||||||
progress_func(file_paths.size(), fileCount);
|
|
||||||
|
|
||||||
if (cancel_func && cancel_func())
|
ret = ReconstructImage(net_noise, im);
|
||||||
return eWaifu2xError_Cancel;
|
|
||||||
|
|
||||||
const auto &input_file = p.first;
|
|
||||||
const auto &output_file = p.second;
|
|
||||||
|
|
||||||
cv::Mat float_image;
|
|
||||||
ret = LoadImage(float_image, input_file);
|
|
||||||
if (ret != eWaifu2xError_OK)
|
if (ret != eWaifu2xError_OK)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// パディングを取り払う
|
||||||
|
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancel_func && cancel_func())
|
||||||
|
return eWaifu2xError_Cancel;
|
||||||
|
|
||||||
|
const int scale2 = ceil(log2(scale_ratio));
|
||||||
|
const double shrinkRatio = scale_ratio / std::pow(2.0, (double)scale2);
|
||||||
|
|
||||||
|
if (isReconstructScale)
|
||||||
|
{
|
||||||
|
bool isError = false;
|
||||||
|
for (int i = 0; i < scale2; i++)
|
||||||
{
|
{
|
||||||
errors.emplace_back(p, ret);
|
Zoom2xAndPaddingImage(im, im, image_size);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat im;
|
ret = ReconstructImage(net_scale, im);
|
||||||
CreateBrightnessImage(float_image, im);
|
|
||||||
|
|
||||||
cv::Size_<int> image_size = 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");
|
|
||||||
|
|
||||||
const bool isReconstructNoise = mode == "noise" || mode == "noise_scale" || (mode == "auto_scale" && isJpeg);
|
|
||||||
const bool isReconstructScale = mode == "scale" || mode == "noise_scale";
|
|
||||||
|
|
||||||
if (isReconstructNoise)
|
|
||||||
{
|
|
||||||
PaddingImage(im, im);
|
|
||||||
|
|
||||||
ret = ReconstructImage(net_noise, im, progress_func);
|
|
||||||
if (ret != eWaifu2xError_OK)
|
if (ret != eWaifu2xError_OK)
|
||||||
{
|
return ret;
|
||||||
errors.emplace_back(p, ret);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// パディングを取り払う
|
// パディングを取り払う
|
||||||
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cancel_func && cancel_func())
|
|
||||||
return eWaifu2xError_Cancel;
|
|
||||||
|
|
||||||
const int scale2 = ceil(log2(scale_ratio));
|
|
||||||
const double shrinkRatio = scale_ratio / std::pow(2.0, (double)scale2);
|
|
||||||
|
|
||||||
if (isReconstructScale)
|
|
||||||
{
|
|
||||||
bool isError = false;
|
|
||||||
for (int i = 0; i < scale2; i++)
|
|
||||||
{
|
|
||||||
Zoom2xAndPaddingImage(im, im, image_size);
|
|
||||||
|
|
||||||
ret = ReconstructImage(net_scale, im, progress_func);
|
|
||||||
if (ret != eWaifu2xError_OK)
|
|
||||||
{
|
|
||||||
errors.emplace_back(p, ret);
|
|
||||||
isError = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// パディングを取り払う
|
|
||||||
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isError)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cancel_func && cancel_func())
|
|
||||||
return eWaifu2xError_Cancel;
|
|
||||||
|
|
||||||
// 再構築した輝度画像とCreateZoomColorImage()で作成した色情報をマージして通常の画像に変換し、書き込む
|
|
||||||
|
|
||||||
std::vector<cv::Mat> color_planes;
|
|
||||||
CreateZoomColorImage(float_image, image_size, color_planes);
|
|
||||||
|
|
||||||
cv::Mat alpha;
|
|
||||||
if (float_image.channels() == 4)
|
|
||||||
{
|
|
||||||
std::vector<cv::Mat> planes;
|
|
||||||
cv::split(float_image, planes);
|
|
||||||
alpha = planes[3];
|
|
||||||
|
|
||||||
cv::resize(alpha, alpha, image_size, 0.0, 0.0, cv::INTER_CUBIC);
|
|
||||||
}
|
|
||||||
|
|
||||||
float_image.release();
|
|
||||||
|
|
||||||
color_planes[0] = im;
|
|
||||||
im.release();
|
|
||||||
|
|
||||||
cv::Mat converted_image;
|
|
||||||
cv::merge(color_planes, converted_image);
|
|
||||||
color_planes.clear();
|
|
||||||
|
|
||||||
cv::Mat process_image;
|
|
||||||
cv::cvtColor(converted_image, process_image, ConvertInverseMode);
|
|
||||||
converted_image.release();
|
|
||||||
|
|
||||||
// アルファチャンネルがあったら、アルファを付加してカラーからアルファの影響を抜く
|
|
||||||
if (!alpha.empty())
|
|
||||||
{
|
|
||||||
std::vector<cv::Mat> planes;
|
|
||||||
cv::split(process_image, planes);
|
|
||||||
process_image.release();
|
|
||||||
|
|
||||||
planes.push_back(alpha);
|
|
||||||
|
|
||||||
cv::Mat w2 = planes[3];
|
|
||||||
|
|
||||||
planes[0] = (planes[0] - 1.0).mul(1.0 / w2) + 1.0;
|
|
||||||
planes[1] = (planes[1] - 1.0).mul(1.0 / w2) + 1.0;
|
|
||||||
planes[2] = (planes[2] - 1.0).mul(1.0 / w2) + 1.0;
|
|
||||||
|
|
||||||
cv::merge(planes, process_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
|
|
||||||
if (image_size.width != ns.width || image_size.height != ns.height)
|
|
||||||
cv::resize(process_image, process_image, ns, 0.0, 0.0, cv::INTER_LINEAR);
|
|
||||||
|
|
||||||
cv::Mat write_iamge;
|
|
||||||
process_image.convertTo(write_iamge, CV_8U, 255.0);
|
|
||||||
process_image.release();
|
|
||||||
|
|
||||||
if (!cv::imwrite(output_file, write_iamge))
|
|
||||||
{
|
|
||||||
errors.emplace_back(p, eWaifu2xError_FailedOpenOutputFile);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
write_iamge.release();
|
|
||||||
|
|
||||||
fileCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress_func)
|
if (cancel_func && cancel_func())
|
||||||
progress_func(file_paths.size(), fileCount);
|
return eWaifu2xError_Cancel;
|
||||||
|
|
||||||
const auto ProcessEndTime = std::chrono::system_clock::now();
|
// 再構築した輝度画像とCreateZoomColorImage()で作成した色情報をマージして通常の画像に変換し、書き込む
|
||||||
|
|
||||||
const auto cuDNNCheckTime = (cuDNNCheckEndTime - cuDNNCheckStartTime);
|
std::vector<cv::Mat> color_planes;
|
||||||
const auto InitTime = (InitEndTime - StartTime) - cuDNNCheckTime;
|
CreateZoomColorImage(float_image, image_size, color_planes);
|
||||||
const auto ProcessTime = (ProcessEndTime - InitEndTime);
|
|
||||||
if (time_func)
|
cv::Mat alpha;
|
||||||
time_func(std::chrono::duration_cast<std::chrono::milliseconds>(InitTime).count()
|
if (float_image.channels() == 4)
|
||||||
, std::chrono::duration_cast<std::chrono::milliseconds>(cuDNNCheckTime).count()
|
{
|
||||||
, std::chrono::duration_cast<std::chrono::milliseconds>(ProcessTime).count(), process_fix);
|
std::vector<cv::Mat> planes;
|
||||||
|
cv::split(float_image, planes);
|
||||||
|
alpha = planes[3];
|
||||||
|
|
||||||
|
cv::resize(alpha, alpha, image_size, 0.0, 0.0, cv::INTER_CUBIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
float_image.release();
|
||||||
|
|
||||||
|
color_planes[0] = im;
|
||||||
|
im.release();
|
||||||
|
|
||||||
|
cv::Mat converted_image;
|
||||||
|
cv::merge(color_planes, converted_image);
|
||||||
|
color_planes.clear();
|
||||||
|
|
||||||
|
cv::Mat process_image;
|
||||||
|
cv::cvtColor(converted_image, process_image, ConvertInverseMode);
|
||||||
|
converted_image.release();
|
||||||
|
|
||||||
|
// アルファチャンネルがあったら、アルファを付加してカラーからアルファの影響を抜く
|
||||||
|
if (!alpha.empty())
|
||||||
|
{
|
||||||
|
std::vector<cv::Mat> planes;
|
||||||
|
cv::split(process_image, planes);
|
||||||
|
process_image.release();
|
||||||
|
|
||||||
|
planes.push_back(alpha);
|
||||||
|
|
||||||
|
cv::Mat w2 = planes[3];
|
||||||
|
|
||||||
|
planes[0] = (planes[0] - 1.0).mul(1.0 / w2) + 1.0;
|
||||||
|
planes[1] = (planes[1] - 1.0).mul(1.0 / w2) + 1.0;
|
||||||
|
planes[2] = (planes[2] - 1.0).mul(1.0 / w2) + 1.0;
|
||||||
|
|
||||||
|
cv::merge(planes, process_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
|
||||||
|
if (image_size.width != ns.width || image_size.height != ns.height)
|
||||||
|
cv::resize(process_image, process_image, ns, 0.0, 0.0, cv::INTER_LINEAR);
|
||||||
|
|
||||||
|
cv::Mat write_iamge;
|
||||||
|
process_image.convertTo(write_iamge, CV_8U, 255.0);
|
||||||
|
process_image.release();
|
||||||
|
|
||||||
|
if (!cv::imwrite(output_file, write_iamge))
|
||||||
|
return eWaifu2xError_FailedOpenOutputFile;
|
||||||
|
|
||||||
|
write_iamge.release();
|
||||||
|
|
||||||
return eWaifu2xError_OK;
|
return eWaifu2xError_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string& Waifu2x::used_process() const
|
||||||
|
{
|
||||||
|
return process;
|
||||||
|
}
|
||||||
|
@ -5,30 +5,71 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
enum eWaifu2xError
|
|
||||||
|
namespace caffe
|
||||||
{
|
{
|
||||||
eWaifu2xError_OK = 0,
|
template <typename Dtype>
|
||||||
eWaifu2xError_Cancel,
|
class Net;
|
||||||
eWaifu2xError_InvalidParameter,
|
|
||||||
eWaifu2xError_FailedOpenInputFile,
|
|
||||||
eWaifu2xError_FailedOpenOutputFile,
|
|
||||||
eWaifu2xError_FailedOpenModelFile,
|
|
||||||
eWaifu2xError_FailedParseModelFile,
|
|
||||||
eWaifu2xError_FailedConstructModel,
|
|
||||||
eWaifu2xError_FailedProcessCaffe,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::pair<std::string, std::string> InputOutputPathPair;
|
class Waifu2x
|
||||||
typedef std::pair<InputOutputPathPair, eWaifu2xError> PathAndErrorPair;
|
{
|
||||||
typedef std::function<bool()> waifu2xCancelFunc;
|
public:
|
||||||
typedef std::function<void(const int ProgressFileMax, const int ProgressFileNow)> waifu2xProgressFunc;
|
enum eWaifu2xError
|
||||||
typedef std::function<void(const uint64_t InitTime, const uint64_t cuDNNCheckTime, const uint64_t ProcessTime, const std::string &Process)> waifu2xTimeFunc;
|
{
|
||||||
|
eWaifu2xError_OK = 0,
|
||||||
|
eWaifu2xError_Cancel,
|
||||||
|
eWaifu2xError_NotInitialized,
|
||||||
|
eWaifu2xError_InvalidParameter,
|
||||||
|
eWaifu2xError_FailedOpenInputFile,
|
||||||
|
eWaifu2xError_FailedOpenOutputFile,
|
||||||
|
eWaifu2xError_FailedOpenModelFile,
|
||||||
|
eWaifu2xError_FailedParseModelFile,
|
||||||
|
eWaifu2xError_FailedConstructModel,
|
||||||
|
eWaifu2xError_FailedProcessCaffe,
|
||||||
|
};
|
||||||
|
|
||||||
bool can_use_cuDNN();
|
typedef std::function<bool()> waifu2xCancelFunc;
|
||||||
|
|
||||||
// mode: noise or scale or noise_scale or auto_scale
|
private:
|
||||||
// process: cpu or gpu or cudnn
|
bool is_inited;
|
||||||
eWaifu2xError waifu2x(int argc, char** argv,
|
|
||||||
const std::vector<InputOutputPathPair> &file_paths, const std::string &mode, const int noise_level, const double scale_ratio, const std::string &model_dir, const std::string &process,
|
std::string mode;
|
||||||
std::vector<PathAndErrorPair> &errors, const waifu2xCancelFunc cancel_func = nullptr, const waifu2xProgressFunc progress_func = nullptr, const waifu2xTimeFunc time_func = nullptr);
|
int noise_level;
|
||||||
|
double scale_ratio;
|
||||||
|
std::string model_dir;
|
||||||
|
std::string process;
|
||||||
|
|
||||||
|
boost::shared_ptr<caffe::Net<float>> net_noise;
|
||||||
|
boost::shared_ptr<caffe::Net<float>> net_scale;
|
||||||
|
|
||||||
|
private:
|
||||||
|
eWaifu2xError LoadImage(cv::Mat &float_image, const std::string &input_file);
|
||||||
|
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 LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std::string ¶m_path);
|
||||||
|
eWaifu2xError ConstractNet(boost::shared_ptr<caffe::Net<float>> &net, const std::string &model_path, const std::string &process);
|
||||||
|
eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat &im);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Waifu2x();
|
||||||
|
~Waifu2x();
|
||||||
|
|
||||||
|
static bool can_use_cuDNN();
|
||||||
|
|
||||||
|
// 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 double scale_ratio, const std::string &model_dir, const std::string &process);
|
||||||
|
|
||||||
|
void destroy();
|
||||||
|
|
||||||
|
eWaifu2xError waifu2x(const std::string &input_file, const std::string &output_file,
|
||||||
|
const waifu2xCancelFunc cancel_func = nullptr);
|
||||||
|
|
||||||
|
const std::string& used_process() const;
|
||||||
|
};
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <chrono>
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/tokenizer.hpp>
|
#include <boost/tokenizer.hpp>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
@ -15,9 +16,8 @@
|
|||||||
#include "CControl.h"
|
#include "CControl.h"
|
||||||
|
|
||||||
#define WM_FAILD_CREATE_DIR (WM_APP + 5)
|
#define WM_FAILD_CREATE_DIR (WM_APP + 5)
|
||||||
#define WM_END_WAIFU2X (WM_APP + 6)
|
#define WM_ON_WAIFU2X_ERROR (WM_APP + 6)
|
||||||
#define WM_END_THREAD (WM_APP + 7)
|
#define WM_END_THREAD (WM_APP + 7)
|
||||||
#define WM_TIME_WAIFU2X (WM_APP + 8)
|
|
||||||
|
|
||||||
const size_t AR_PATH_MAX(1024);
|
const size_t AR_PATH_MAX(1024);
|
||||||
|
|
||||||
@ -83,13 +83,12 @@ private:
|
|||||||
std::string autoSetAddName;
|
std::string autoSetAddName;
|
||||||
bool isLastError;
|
bool isLastError;
|
||||||
|
|
||||||
struct stWaifu2xTime
|
std::string logMessage;
|
||||||
{
|
|
||||||
uint64_t InitTime;
|
std::string usedProcess;
|
||||||
uint64_t cuDNNCheckTime;
|
std::chrono::system_clock::duration cuDNNCheckTime;
|
||||||
uint64_t ProcessTime;
|
std::chrono::system_clock::duration InitTime;
|
||||||
std::string Process;
|
std::chrono::system_clock::duration ProcessTime;
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string AddName() const
|
std::string AddName() const
|
||||||
@ -184,7 +183,7 @@ private:
|
|||||||
{
|
{
|
||||||
const boost::filesystem::path input_path(boost::filesystem::absolute(input_str));
|
const boost::filesystem::path input_path(boost::filesystem::absolute(input_str));
|
||||||
|
|
||||||
std::vector<InputOutputPathPair> file_paths;
|
std::vector<std::pair<std::string, std::string>> file_paths;
|
||||||
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
||||||
{
|
{
|
||||||
boost::filesystem::path output_path(output_str);
|
boost::filesystem::path output_path(output_str);
|
||||||
@ -273,24 +272,46 @@ private:
|
|||||||
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, ProgressFileNow, 0);
|
SendMessage(GetDlgItem(dh, IDC_PROGRESS), PBM_SETPOS, ProgressFileNow, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto TimeFunc = [this](const uint64_t InitTime, const uint64_t cuDNNCheckTime, const uint64_t ProcessTime, const std::string &Process)
|
const auto cuDNNCheckStartTime = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
if (process == "gpu")
|
||||||
|
Waifu2x::can_use_cuDNN();
|
||||||
|
|
||||||
|
const auto cuDNNCheckEndTime = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
Waifu2x::eWaifu2xError ret;
|
||||||
|
|
||||||
|
Waifu2x w;
|
||||||
|
ret = w.init(__argc, __argv, mode, noise_level, scale_ratio, "models", process);
|
||||||
|
if(ret != Waifu2x::eWaifu2xError_OK)
|
||||||
|
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, 0);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
stWaifu2xTime t;
|
const auto InitEndTime = std::chrono::system_clock::now();
|
||||||
t.InitTime = InitTime;
|
|
||||||
t.cuDNNCheckTime = cuDNNCheckTime;
|
|
||||||
t.ProcessTime = ProcessTime;
|
|
||||||
t.Process = Process;
|
|
||||||
|
|
||||||
SendMessage(dh, WM_TIME_WAIFU2X, (WPARAM)&t, 0);
|
for (const auto &p : file_paths)
|
||||||
};
|
{
|
||||||
|
ret = w.waifu2x(p.first, p.second, [this]()
|
||||||
|
{
|
||||||
|
return cancelFlag;
|
||||||
|
});
|
||||||
|
|
||||||
std::vector<PathAndErrorPair> errors;
|
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||||
const eWaifu2xError ret = waifu2x(__argc, __argv, file_paths, mode, noise_level, scale_ratio, "models", process, errors, [this]()
|
{
|
||||||
{
|
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, (LPARAM)&p);
|
||||||
return cancelFlag;
|
|
||||||
}, ProgessFunc, TimeFunc);
|
|
||||||
|
|
||||||
SendMessage(dh, WM_END_WAIFU2X, (WPARAM)&ret, (LPARAM)&errors);
|
if (ret == Waifu2x::eWaifu2xError_Cancel)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ProcessEndTime = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
cuDNNCheckTime = cuDNNCheckEndTime - cuDNNCheckStartTime;
|
||||||
|
InitTime = InitEndTime - cuDNNCheckEndTime;
|
||||||
|
ProcessTime = ProcessEndTime - InitEndTime;
|
||||||
|
usedProcess = w.used_process();
|
||||||
|
}
|
||||||
|
|
||||||
PostMessage(dh, WM_END_THREAD, 0, 0);
|
PostMessage(dh, WM_END_THREAD, 0, 0);
|
||||||
}
|
}
|
||||||
@ -317,6 +338,64 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddLogMessage(const char *msg)
|
||||||
|
{
|
||||||
|
if (logMessage.length() == 0)
|
||||||
|
logMessage += msg;
|
||||||
|
else
|
||||||
|
logMessage += std::string("\r\n") + msg;
|
||||||
|
|
||||||
|
SetWindowTextA(GetDlgItem(dh, IDC_EDIT_LOG), logMessage.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Waifu2xTime()
|
||||||
|
{
|
||||||
|
char msg[1024 * 2];
|
||||||
|
char *ptr = msg;
|
||||||
|
|
||||||
|
{
|
||||||
|
std::string p(usedProcess);
|
||||||
|
if (p == "cpu")
|
||||||
|
p = "CPU";
|
||||||
|
else if (p == "gpu")
|
||||||
|
p = "GPU";
|
||||||
|
else if (p == "cudnn")
|
||||||
|
p = "cuDNN";
|
||||||
|
|
||||||
|
ptr += sprintf(ptr, "使用プロセッサーモード: %s\r\n", p.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(ProcessTime).count();
|
||||||
|
const int msec = t % 1000; t /= 1000;
|
||||||
|
const int sec = t % 60; t /= 60;
|
||||||
|
const int min = t % 60; t /= 60;
|
||||||
|
const int hour = (int)t;
|
||||||
|
ptr += sprintf(ptr, "処理時間: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(InitTime).count();
|
||||||
|
const int msec = t % 1000; t /= 1000;
|
||||||
|
const int sec = t % 60; t /= 60;
|
||||||
|
const int min = t % 60; t /= 60;
|
||||||
|
const int hour = (int)t;
|
||||||
|
ptr += sprintf(ptr, "初期化時間: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process == "gpu" || process == "cudnn")
|
||||||
|
{
|
||||||
|
uint64_t t = std::chrono::duration_cast<std::chrono::milliseconds>(cuDNNCheckTime).count();
|
||||||
|
const int msec = t % 1000; t /= 1000;
|
||||||
|
const int sec = t % 60; t /= 60;
|
||||||
|
const int min = t % 60; t /= 60;
|
||||||
|
const int hour = (int)t;
|
||||||
|
ptr += sprintf(ptr, "cuDNNチェック時間: %02d:%02d:%02d.%d", hour, min, sec, msec);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddLogMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DialogEvent() : dh(nullptr), mode("noise_scale"), noise_level(1), scale_ratio(2.0), process("gpu"), outputExt("png"), inputFileExt("png:jpg:jpeg:tif:tiff:bmp"), isLastError(false)
|
DialogEvent() : dh(nullptr), mode("noise_scale"), noise_level(1), scale_ratio(2.0), process("gpu"), outputExt("png"), inputFileExt("png:jpg:jpeg:tif:tiff:bmp"), isLastError(false)
|
||||||
{
|
{
|
||||||
@ -357,6 +436,7 @@ public:
|
|||||||
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), FALSE);
|
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), FALSE);
|
||||||
|
|
||||||
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_LOG), "");
|
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_LOG), "");
|
||||||
|
logMessage.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaitThreadExit(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
void WaitThreadExit(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||||
@ -366,57 +446,15 @@ public:
|
|||||||
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), TRUE);
|
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), TRUE);
|
||||||
|
|
||||||
if (!isLastError)
|
if (!isLastError)
|
||||||
|
{
|
||||||
|
if (!cancelFlag)
|
||||||
|
AddLogMessage("変換に成功しました");
|
||||||
|
|
||||||
|
Waifu2xTime();
|
||||||
MessageBeep(MB_ICONASTERISK);
|
MessageBeep(MB_ICONASTERISK);
|
||||||
}
|
|
||||||
|
|
||||||
void Waifu2xTime(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
|
||||||
{
|
|
||||||
const stWaifu2xTime *tp = (const stWaifu2xTime *)wParam;
|
|
||||||
|
|
||||||
char msg[1024*2];
|
|
||||||
char *ptr = msg;
|
|
||||||
|
|
||||||
{
|
|
||||||
std::string p(tp->Process);
|
|
||||||
if (p == "cpu")
|
|
||||||
p = "CPU";
|
|
||||||
else if (p == "gpu")
|
|
||||||
p = "GPU";
|
|
||||||
else if (p == "cudnn")
|
|
||||||
p = "cuDNN";
|
|
||||||
|
|
||||||
ptr += sprintf(ptr, "使用プロセッサーモード: %s\r\n", p.c_str());
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
{
|
MessageBoxA(dh, "エラーが発生しました", "エラー", MB_OK | MB_ICONERROR);
|
||||||
uint64_t t = tp->ProcessTime;
|
|
||||||
const int msec = t % 1000; t /= 1000;
|
|
||||||
const int sec = t % 60; t /= 60;
|
|
||||||
const int min = t % 60; t /= 60;
|
|
||||||
const int hour = (int)t;
|
|
||||||
ptr += sprintf(ptr, "処理時間: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
uint64_t t = tp->InitTime;
|
|
||||||
const int msec = t % 1000; t /= 1000;
|
|
||||||
const int sec = t % 60; t /= 60;
|
|
||||||
const int min = t % 60; t /= 60;
|
|
||||||
const int hour = (int)t;
|
|
||||||
ptr += sprintf(ptr, "初期化時間: %02d:%02d:%02d.%d\r\n", hour, min, sec, msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tp->Process == "gpu" || tp->Process == "cudnn")
|
|
||||||
{
|
|
||||||
uint64_t t = tp->cuDNNCheckTime;
|
|
||||||
const int msec = t % 1000; t /= 1000;
|
|
||||||
const int sec = t % 60; t /= 60;
|
|
||||||
const int min = t % 60; t /= 60;
|
|
||||||
const int hour = (int)t;
|
|
||||||
ptr += sprintf(ptr, "cuDNNチェック時間: %02d:%02d:%02d.%d", hour, min, sec, msec);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_LOG), msg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnDialogEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
void OnDialogEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||||
@ -441,63 +479,63 @@ public:
|
|||||||
isLastError = true;
|
isLastError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnEndWaifu2x(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
void OnWaifu2xError(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||||
{
|
{
|
||||||
const eWaifu2xError ret = *(const eWaifu2xError *)wParam;
|
const Waifu2x::eWaifu2xError ret = *(const Waifu2x::eWaifu2xError *)wParam;
|
||||||
const std::vector<PathAndErrorPair> &errors = *(const std::vector<PathAndErrorPair> *)lParam;
|
|
||||||
|
|
||||||
if ((ret != eWaifu2xError_OK) || errors.size() > 0)
|
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||||
{
|
{
|
||||||
char msg[1024] = "";
|
char msg[1024] = "";
|
||||||
|
|
||||||
switch (ret)
|
if (lParam == 0)
|
||||||
{
|
{
|
||||||
case eWaifu2xError_Cancel:
|
switch (ret)
|
||||||
sprintf(msg, "キャンセルされました");
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_InvalidParameter:
|
|
||||||
sprintf(msg, "パラメータが不正です");
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedOpenModelFile:
|
|
||||||
sprintf(msg, "モデルファイルが開けませんでした");
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedParseModelFile:
|
|
||||||
sprintf(msg, "モデルファイルが壊れています");
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedConstructModel:
|
|
||||||
sprintf(msg, "ネットワークの構築に失敗しました");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == eWaifu2xError_OK)
|
|
||||||
{
|
|
||||||
// 全てのエラーを表示することは出来ないので最初の一つだけ表示
|
|
||||||
|
|
||||||
const auto &fp = errors[0].first;
|
|
||||||
|
|
||||||
bool isBreak = false;
|
|
||||||
switch (errors[0].second)
|
|
||||||
{
|
{
|
||||||
case eWaifu2xError_InvalidParameter:
|
case Waifu2x::eWaifu2xError_Cancel:
|
||||||
|
sprintf(msg, "キャンセルされました");
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||||
sprintf(msg, "パラメータが不正です");
|
sprintf(msg, "パラメータが不正です");
|
||||||
break;
|
break;
|
||||||
case eWaifu2xError_FailedOpenInputFile:
|
case Waifu2x::eWaifu2xError_FailedOpenModelFile:
|
||||||
//sprintf(msg, "入力画像「%s」が開けませんでした", fp.first.c_str());
|
sprintf(msg, "モデルファイルが開けませんでした");
|
||||||
sprintf(msg, "入力画像が開けませんでした");
|
|
||||||
break;
|
break;
|
||||||
case eWaifu2xError_FailedOpenOutputFile:
|
case Waifu2x::eWaifu2xError_FailedParseModelFile:
|
||||||
//sprintf(msg, "出力画像「%s」が書き込めませんでした", fp.second.c_str());
|
sprintf(msg, "モデルファイルが壊れています");
|
||||||
sprintf(msg, "出力画像が書き込めませんでした");
|
|
||||||
break;
|
break;
|
||||||
case eWaifu2xError_FailedProcessCaffe:
|
case Waifu2x::eWaifu2xError_FailedConstructModel:
|
||||||
|
sprintf(msg, "ネットワークの構築に失敗しました");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto &fp = *(const std::pair<std::string, std::string> *)lParam;
|
||||||
|
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case Waifu2x::eWaifu2xError_Cancel:
|
||||||
|
sprintf(msg, "キャンセルされました");
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||||
|
sprintf(msg, "パラメータが不正です");
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedOpenInputFile:
|
||||||
|
sprintf(msg, "入力画像「%s」が開けませんでした", fp.first.c_str());
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedOpenOutputFile:
|
||||||
|
sprintf(msg, "出力画像を「%s」に書き込めませんでした", fp.second.c_str());
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedProcessCaffe:
|
||||||
sprintf(msg, "補間処理に失敗しました");
|
sprintf(msg, "補間処理に失敗しました");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBoxA(dh, msg, "エラー", MB_OK | MB_ICONERROR);
|
AddLogMessage(msg);
|
||||||
|
|
||||||
isLastError = true;
|
if (ret != Waifu2x::eWaifu2xError_Cancel)
|
||||||
|
isLastError = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,7 +568,7 @@ public:
|
|||||||
|
|
||||||
void CheckCUDNN(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
void CheckCUDNN(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||||
{
|
{
|
||||||
if (can_use_cuDNN())
|
if (Waifu2x::can_use_cuDNN())
|
||||||
MessageBox(dh, TEXT("cuDNNが使えます"), TEXT("結果"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(dh, TEXT("cuDNNが使えます"), TEXT("結果"), MB_OK | MB_ICONINFORMATION);
|
||||||
else
|
else
|
||||||
MessageBox(dh, TEXT("cuDNNは使えません"), TEXT("結果"), MB_OK | MB_ICONERROR);
|
MessageBox(dh, TEXT("cuDNNは使えません"), TEXT("結果"), MB_OK | MB_ICONERROR);
|
||||||
@ -664,9 +702,8 @@ int WINAPI WinMain(HINSTANCE hInstance,
|
|||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::Create, &cDialogEvent), NULL, WM_INITDIALOG);
|
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::Create, &cDialogEvent), NULL, WM_INITDIALOG);
|
||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnDialogEnd, &cDialogEvent), NULL, WM_CLOSE);
|
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnDialogEnd, &cDialogEvent), NULL, WM_CLOSE);
|
||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnFaildCreateDir, &cDialogEvent), NULL, WM_FAILD_CREATE_DIR);
|
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnFaildCreateDir, &cDialogEvent), NULL, WM_FAILD_CREATE_DIR);
|
||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnEndWaifu2x, &cDialogEvent), NULL, WM_END_WAIFU2X);
|
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::OnWaifu2xError, &cDialogEvent), NULL, WM_ON_WAIFU2X_ERROR);
|
||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::WaitThreadExit, &cDialogEvent), NULL, WM_END_THREAD);
|
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::WaitThreadExit, &cDialogEvent), NULL, WM_END_THREAD);
|
||||||
cDialog.SetEventCallBack(SetClassFunc(DialogEvent::Waifu2xTime, &cDialogEvent), NULL, WM_TIME_WAIFU2X);
|
|
||||||
|
|
||||||
// ダイアログを表示
|
// ダイアログを表示
|
||||||
cDialog.DoModal(hInstance, IDD_DIALOG);
|
cDialog.DoModal(hInstance, IDD_DIALOG);
|
||||||
|
@ -120,7 +120,7 @@ int main(int argc, char** argv)
|
|||||||
if (outputExt.length() > 0 && outputExt[0] != '.')
|
if (outputExt.length() > 0 && outputExt[0] != '.')
|
||||||
outputExt = "." + outputExt;
|
outputExt = "." + outputExt;
|
||||||
|
|
||||||
std::vector<InputOutputPathPair> file_paths;
|
std::vector<std::pair<std::string, std::string>> file_paths;
|
||||||
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
if (boost::filesystem::is_directory(input_path)) // input_pathがフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
||||||
{
|
{
|
||||||
boost::filesystem::path output_path;
|
boost::filesystem::path output_path;
|
||||||
@ -227,51 +227,58 @@ int main(int argc, char** argv)
|
|||||||
file_paths.emplace_back(cmdInputFile.getValue(), outputFileName);
|
file_paths.emplace_back(cmdInputFile.getValue(), outputFileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PathAndErrorPair> errors;
|
Waifu2x::eWaifu2xError ret;
|
||||||
|
Waifu2x w;
|
||||||
const eWaifu2xError ret = waifu2x(argc, argv, file_paths, cmdMode.getValue(), cmdNRLevel.getValue(), cmdScaleRatio.getValue(), cmdModelPath.getValue(), cmdProcess.getValue(), errors);
|
ret = w.init(argc, argv, cmdMode.getValue(), cmdNRLevel.getValue(), cmdScaleRatio.getValue(), cmdModelPath.getValue(), cmdProcess.getValue());
|
||||||
if (ret != eWaifu2xError_OK || errors.size() > 0)
|
switch (ret)
|
||||||
{
|
{
|
||||||
switch (ret)
|
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||||
{
|
printf("エラー: パラメータが不正です\n");
|
||||||
case eWaifu2xError_InvalidParameter:
|
return 1;
|
||||||
printf("エラー: パラメータが不正です\n");
|
case Waifu2x::eWaifu2xError_FailedOpenModelFile:
|
||||||
break;
|
printf("エラー: モデルファイルが開けませんでした\n");
|
||||||
case eWaifu2xError_FailedOpenModelFile:
|
return 1;
|
||||||
printf("エラー: モデルファイルが開けませんでした\n");
|
case Waifu2x::eWaifu2xError_FailedParseModelFile:
|
||||||
break;
|
printf("エラー: モデルファイルが壊れています\n");
|
||||||
case eWaifu2xError_FailedParseModelFile:
|
return 1;
|
||||||
printf("エラー: モデルファイルが壊れています\n");
|
case Waifu2x::eWaifu2xError_FailedConstructModel:
|
||||||
break;
|
printf("エラー: ネットワークの構築に失敗しました\n");
|
||||||
case eWaifu2xError_FailedConstructModel:
|
|
||||||
printf("エラー: ネットワークの構築に失敗しました\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &ep : errors)
|
|
||||||
{
|
|
||||||
const auto &fp = ep.first;
|
|
||||||
|
|
||||||
switch (ep.second)
|
|
||||||
{
|
|
||||||
case eWaifu2xError_InvalidParameter:
|
|
||||||
printf("エラー: パラメータが不正です\n");
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedOpenInputFile:
|
|
||||||
printf("エラー: 入力画像「%s」が開けませんでした\n", fp.first.c_str());
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedOpenOutputFile:
|
|
||||||
printf("エラー: 出力画像「%s」が書き込めませんでした\n", fp.second.c_str());
|
|
||||||
break;
|
|
||||||
case eWaifu2xError_FailedProcessCaffe:
|
|
||||||
printf("エラー: 補間処理に失敗しました\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("変換に失敗しました\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isError = false;
|
||||||
|
for (const auto &p : file_paths)
|
||||||
|
{
|
||||||
|
const Waifu2x::eWaifu2xError ret = w.waifu2x(p.first, p.second);
|
||||||
|
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||||
|
{
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||||
|
printf("エラー: パラメータが不正です\n");
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedOpenInputFile:
|
||||||
|
printf("エラー: 入力画像「%s」が開けませんでした\n", p.first.c_str());
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedOpenOutputFile:
|
||||||
|
printf("エラー: 出力画像「%s」が書き込めませんでした\n", p.second.c_str());
|
||||||
|
break;
|
||||||
|
case Waifu2x::eWaifu2xError_FailedProcessCaffe:
|
||||||
|
printf("エラー: 補間処理に失敗しました\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
isError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isError)
|
||||||
|
{
|
||||||
|
printf("変換に失敗したファイルがあります\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("変換に成功しました\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user