mirror of
https://github.com/lltcggie/waifu2x-caffe.git
synced 2025-06-26 05:32:47 +00:00
全体の設計を変更
This commit is contained in:
parent
a78fbbf322
commit
a2b222ee12
@ -11,6 +11,8 @@
|
||||
|
||||
#if defined(WIN32) || defined(WIN64)
|
||||
#include <Windows.h>
|
||||
|
||||
#undef LoadImage
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -42,12 +44,21 @@ const auto original_width_height = 128 + layer_num * 2;
|
||||
const int ConvertMode = CV_RGB2YUV;
|
||||
const int ConvertInverseMode = CV_YUV2RGB;
|
||||
|
||||
std::once_flag waifu2x_once_flag;
|
||||
std::once_flag waifu2x_cudnn_once_flag;
|
||||
static std::once_flag waifu2x_once_flag;
|
||||
static std::once_flag waifu2x_cudnn_once_flag;
|
||||
|
||||
|
||||
Waifu2x::Waifu2x() : is_inited(false)
|
||||
{
|
||||
}
|
||||
|
||||
Waifu2x::~Waifu2x()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
// cuDNNが使えるかチェック。現状Windowsのみ
|
||||
bool can_use_cuDNN()
|
||||
bool Waifu2x::can_use_cuDNN()
|
||||
{
|
||||
static bool cuDNNFlag = false;
|
||||
std::call_once(waifu2x_cudnn_once_flag, [&]()
|
||||
@ -80,7 +91,7 @@ bool can_use_cuDNN()
|
||||
}
|
||||
|
||||
// 画像を読み込んで値を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);
|
||||
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::cvtColor(float_image, converted_color, ConvertMode);
|
||||
@ -131,7 +142,7 @@ eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im)
|
||||
|
||||
// 入力画像の(Photoshopでいう)キャンバスサイズをoutput_sizeの倍数に変更
|
||||
// 画像は左上配置、余白は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 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()でパディングする
|
||||
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.width *= 2;
|
||||
@ -161,7 +172,7 @@ eWaifu2xError Zoom2xAndPaddingImage(const cv::Mat &input, cv::Mat &output, cv::S
|
||||
}
|
||||
|
||||
// 入力画像を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::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;
|
||||
std::vector<char> jsonBuf;
|
||||
@ -295,7 +306,7 @@ eWaifu2xError LoadParameter(boost::shared_ptr<caffe::Net<float>> net, const std:
|
||||
|
||||
// モデルファイルからネットワークを構築
|
||||
// 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;
|
||||
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 Width = im.size().width;
|
||||
@ -464,18 +475,21 @@ eWaifu2xError ReconstructImage(boost::shared_ptr<caffe::Net<float>> net, cv::Mat
|
||||
return eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
#include <boost/timer.hpp>
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
if (scale_ratio <= 0.0)
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
|
||||
if (is_inited)
|
||||
return eWaifu2xError_OK;
|
||||
|
||||
if (ScaleRatio <= 0.0)
|
||||
return eWaifu2xError_InvalidParameter;
|
||||
|
||||
const auto StartTime = std::chrono::system_clock::now();
|
||||
|
||||
eWaifu2xError ret;
|
||||
mode = Mode;
|
||||
noise_level = NoiseLevel;
|
||||
scale_ratio = ScaleRatio;
|
||||
model_dir = ModelDir;
|
||||
process = Process;
|
||||
|
||||
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();
|
||||
|
||||
std::string process_fix(process);
|
||||
if (process_fix == "gpu")
|
||||
if (process == "gpu")
|
||||
{
|
||||
// cuDNNが使えそうならcuDNNを使う
|
||||
if (can_use_cuDNN())
|
||||
process_fix = "cudnn";
|
||||
process = "cudnn";
|
||||
}
|
||||
|
||||
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))
|
||||
return eWaifu2xError_FailedOpenModelFile;
|
||||
|
||||
if (process_fix == "cpu")
|
||||
if (process == "cpu")
|
||||
caffe::Caffe::set_mode(caffe::Caffe::CPU);
|
||||
else
|
||||
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")
|
||||
{
|
||||
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();
|
||||
|
||||
ret = ConstractNet(net_noise, model_path, process_fix);
|
||||
ret = ConstractNet(net_noise, model_path, process);
|
||||
if (ret != eWaifu2xError_OK)
|
||||
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 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)
|
||||
return ret;
|
||||
|
||||
@ -552,27 +562,31 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
||||
return ret;
|
||||
}
|
||||
|
||||
const auto InitEndTime = std::chrono::system_clock::now();
|
||||
is_inited = true;
|
||||
|
||||
int fileCount = 0;
|
||||
for (const auto &p : file_paths)
|
||||
{
|
||||
if (progress_func)
|
||||
progress_func(file_paths.size(), fileCount);
|
||||
return eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
if (cancel_func && cancel_func())
|
||||
return eWaifu2xError_Cancel;
|
||||
void Waifu2x::destroy()
|
||||
{
|
||||
net_noise.reset();
|
||||
net_scale.reset();
|
||||
|
||||
const auto &input_file = p.first;
|
||||
const auto &output_file = p.second;
|
||||
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)
|
||||
{
|
||||
errors.emplace_back(p, ret);
|
||||
continue;
|
||||
}
|
||||
return ret;
|
||||
|
||||
cv::Mat im;
|
||||
CreateBrightnessImage(float_image, im);
|
||||
@ -591,12 +605,9 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
||||
{
|
||||
PaddingImage(im, im);
|
||||
|
||||
ret = ReconstructImage(net_noise, im, progress_func);
|
||||
ret = ReconstructImage(net_noise, im);
|
||||
if (ret != eWaifu2xError_OK)
|
||||
{
|
||||
errors.emplace_back(p, ret);
|
||||
continue;
|
||||
}
|
||||
return ret;
|
||||
|
||||
// パディングを取り払う
|
||||
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
||||
@ -615,20 +626,13 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
||||
{
|
||||
Zoom2xAndPaddingImage(im, im, image_size);
|
||||
|
||||
ret = ReconstructImage(net_scale, im, progress_func);
|
||||
ret = ReconstructImage(net_scale, im);
|
||||
if (ret != eWaifu2xError_OK)
|
||||
{
|
||||
errors.emplace_back(p, ret);
|
||||
isError = true;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
|
||||
// パディングを取り払う
|
||||
im = im(cv::Rect(offset, offset, image_size.width, image_size.height));
|
||||
}
|
||||
|
||||
if (isError)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cancel_func && cancel_func())
|
||||
@ -689,28 +693,14 @@ eWaifu2xError waifu2x(int argc, char** argv, const std::vector<InputOutputPathPa
|
||||
process_image.release();
|
||||
|
||||
if (!cv::imwrite(output_file, write_iamge))
|
||||
{
|
||||
errors.emplace_back(p, eWaifu2xError_FailedOpenOutputFile);
|
||||
continue;
|
||||
}
|
||||
return eWaifu2xError_FailedOpenOutputFile;
|
||||
|
||||
write_iamge.release();
|
||||
|
||||
fileCount++;
|
||||
}
|
||||
|
||||
if (progress_func)
|
||||
progress_func(file_paths.size(), fileCount);
|
||||
|
||||
const auto ProcessEndTime = std::chrono::system_clock::now();
|
||||
|
||||
const auto cuDNNCheckTime = (cuDNNCheckEndTime - cuDNNCheckStartTime);
|
||||
const auto InitTime = (InitEndTime - StartTime) - cuDNNCheckTime;
|
||||
const auto ProcessTime = (ProcessEndTime - InitEndTime);
|
||||
if (time_func)
|
||||
time_func(std::chrono::duration_cast<std::chrono::milliseconds>(InitTime).count()
|
||||
, std::chrono::duration_cast<std::chrono::milliseconds>(cuDNNCheckTime).count()
|
||||
, std::chrono::duration_cast<std::chrono::milliseconds>(ProcessTime).count(), process_fix);
|
||||
|
||||
return eWaifu2xError_OK;
|
||||
}
|
||||
|
||||
const std::string& Waifu2x::used_process() const
|
||||
{
|
||||
return process;
|
||||
}
|
||||
|
@ -5,11 +5,24 @@
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <functional>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
enum eWaifu2xError
|
||||
|
||||
namespace caffe
|
||||
{
|
||||
template <typename Dtype>
|
||||
class Net;
|
||||
};
|
||||
|
||||
class Waifu2x
|
||||
{
|
||||
public:
|
||||
enum eWaifu2xError
|
||||
{
|
||||
eWaifu2xError_OK = 0,
|
||||
eWaifu2xError_Cancel,
|
||||
eWaifu2xError_NotInitialized,
|
||||
eWaifu2xError_InvalidParameter,
|
||||
eWaifu2xError_FailedOpenInputFile,
|
||||
eWaifu2xError_FailedOpenOutputFile,
|
||||
@ -17,18 +30,46 @@ enum eWaifu2xError
|
||||
eWaifu2xError_FailedParseModelFile,
|
||||
eWaifu2xError_FailedConstructModel,
|
||||
eWaifu2xError_FailedProcessCaffe,
|
||||
};
|
||||
|
||||
typedef std::function<bool()> waifu2xCancelFunc;
|
||||
|
||||
private:
|
||||
bool is_inited;
|
||||
|
||||
std::string mode;
|
||||
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;
|
||||
};
|
||||
|
||||
typedef std::pair<std::string, std::string> InputOutputPathPair;
|
||||
typedef std::pair<InputOutputPathPair, eWaifu2xError> PathAndErrorPair;
|
||||
typedef std::function<bool()> waifu2xCancelFunc;
|
||||
typedef std::function<void(const int ProgressFileMax, const int ProgressFileNow)> waifu2xProgressFunc;
|
||||
typedef std::function<void(const uint64_t InitTime, const uint64_t cuDNNCheckTime, const uint64_t ProcessTime, const std::string &Process)> waifu2xTimeFunc;
|
||||
|
||||
bool can_use_cuDNN();
|
||||
|
||||
// mode: noise or scale or noise_scale or auto_scale
|
||||
// process: cpu or gpu or cudnn
|
||||
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 = nullptr, const waifu2xProgressFunc progress_func = nullptr, const waifu2xTimeFunc time_func = nullptr);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
@ -15,9 +16,8 @@
|
||||
#include "CControl.h"
|
||||
|
||||
#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_TIME_WAIFU2X (WM_APP + 8)
|
||||
|
||||
const size_t AR_PATH_MAX(1024);
|
||||
|
||||
@ -83,13 +83,12 @@ private:
|
||||
std::string autoSetAddName;
|
||||
bool isLastError;
|
||||
|
||||
struct stWaifu2xTime
|
||||
{
|
||||
uint64_t InitTime;
|
||||
uint64_t cuDNNCheckTime;
|
||||
uint64_t ProcessTime;
|
||||
std::string Process;
|
||||
};
|
||||
std::string logMessage;
|
||||
|
||||
std::string usedProcess;
|
||||
std::chrono::system_clock::duration cuDNNCheckTime;
|
||||
std::chrono::system_clock::duration InitTime;
|
||||
std::chrono::system_clock::duration ProcessTime;
|
||||
|
||||
private:
|
||||
std::string AddName() const
|
||||
@ -184,7 +183,7 @@ private:
|
||||
{
|
||||
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がフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
||||
{
|
||||
boost::filesystem::path output_path(output_str);
|
||||
@ -273,24 +272,46 @@ private:
|
||||
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;
|
||||
t.InitTime = InitTime;
|
||||
t.cuDNNCheckTime = cuDNNCheckTime;
|
||||
t.ProcessTime = ProcessTime;
|
||||
t.Process = Process;
|
||||
const auto InitEndTime = std::chrono::system_clock::now();
|
||||
|
||||
SendMessage(dh, WM_TIME_WAIFU2X, (WPARAM)&t, 0);
|
||||
};
|
||||
|
||||
std::vector<PathAndErrorPair> errors;
|
||||
const eWaifu2xError ret = waifu2x(__argc, __argv, file_paths, mode, noise_level, scale_ratio, "models", process, errors, [this]()
|
||||
for (const auto &p : file_paths)
|
||||
{
|
||||
ret = w.waifu2x(p.first, p.second, [this]()
|
||||
{
|
||||
return cancelFlag;
|
||||
}, ProgessFunc, TimeFunc);
|
||||
});
|
||||
|
||||
SendMessage(dh, WM_END_WAIFU2X, (WPARAM)&ret, (LPARAM)&errors);
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
{
|
||||
SendMessage(dh, WM_ON_WAIFU2X_ERROR, (WPARAM)&ret, (LPARAM)&p);
|
||||
|
||||
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);
|
||||
}
|
||||
@ -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:
|
||||
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);
|
||||
|
||||
SetWindowTextA(GetDlgItem(hWnd, IDC_EDIT_LOG), "");
|
||||
logMessage.clear();
|
||||
}
|
||||
|
||||
void WaitThreadExit(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
@ -366,57 +446,15 @@ public:
|
||||
EnableWindow(GetDlgItem(dh, IDC_BUTTON_EXEC), TRUE);
|
||||
|
||||
if (!isLastError)
|
||||
{
|
||||
if (!cancelFlag)
|
||||
AddLogMessage("変換に成功しました");
|
||||
|
||||
Waifu2xTime();
|
||||
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());
|
||||
}
|
||||
|
||||
{
|
||||
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);
|
||||
else
|
||||
MessageBoxA(dh, "エラーが発生しました", "エラー", MB_OK | MB_ICONERROR);
|
||||
}
|
||||
|
||||
void OnDialogEnd(HWND hWnd, WPARAM wParam, LPARAM lParam, LPVOID lpData)
|
||||
@ -441,62 +479,62 @@ public:
|
||||
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 std::vector<PathAndErrorPair> &errors = *(const std::vector<PathAndErrorPair> *)lParam;
|
||||
const Waifu2x::eWaifu2xError ret = *(const Waifu2x::eWaifu2xError *)wParam;
|
||||
|
||||
if ((ret != eWaifu2xError_OK) || errors.size() > 0)
|
||||
if (ret != Waifu2x::eWaifu2xError_OK)
|
||||
{
|
||||
char msg[1024] = "";
|
||||
|
||||
if (lParam == 0)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case eWaifu2xError_Cancel:
|
||||
case Waifu2x::eWaifu2xError_Cancel:
|
||||
sprintf(msg, "キャンセルされました");
|
||||
break;
|
||||
case eWaifu2xError_InvalidParameter:
|
||||
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||
sprintf(msg, "パラメータが不正です");
|
||||
break;
|
||||
case eWaifu2xError_FailedOpenModelFile:
|
||||
case Waifu2x::eWaifu2xError_FailedOpenModelFile:
|
||||
sprintf(msg, "モデルファイルが開けませんでした");
|
||||
break;
|
||||
case eWaifu2xError_FailedParseModelFile:
|
||||
case Waifu2x::eWaifu2xError_FailedParseModelFile:
|
||||
sprintf(msg, "モデルファイルが壊れています");
|
||||
break;
|
||||
case eWaifu2xError_FailedConstructModel:
|
||||
case Waifu2x::eWaifu2xError_FailedConstructModel:
|
||||
sprintf(msg, "ネットワークの構築に失敗しました");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == eWaifu2xError_OK)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 全てのエラーを表示することは出来ないので最初の一つだけ表示
|
||||
const auto &fp = *(const std::pair<std::string, std::string> *)lParam;
|
||||
|
||||
const auto &fp = errors[0].first;
|
||||
|
||||
bool isBreak = false;
|
||||
switch (errors[0].second)
|
||||
switch (ret)
|
||||
{
|
||||
case eWaifu2xError_InvalidParameter:
|
||||
case Waifu2x::eWaifu2xError_Cancel:
|
||||
sprintf(msg, "キャンセルされました");
|
||||
break;
|
||||
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||
sprintf(msg, "パラメータが不正です");
|
||||
break;
|
||||
case eWaifu2xError_FailedOpenInputFile:
|
||||
//sprintf(msg, "入力画像「%s」が開けませんでした", fp.first.c_str());
|
||||
sprintf(msg, "入力画像が開けませんでした");
|
||||
case Waifu2x::eWaifu2xError_FailedOpenInputFile:
|
||||
sprintf(msg, "入力画像「%s」が開けませんでした", fp.first.c_str());
|
||||
break;
|
||||
case eWaifu2xError_FailedOpenOutputFile:
|
||||
//sprintf(msg, "出力画像「%s」が書き込めませんでした", fp.second.c_str());
|
||||
sprintf(msg, "出力画像が書き込めませんでした");
|
||||
case Waifu2x::eWaifu2xError_FailedOpenOutputFile:
|
||||
sprintf(msg, "出力画像を「%s」に書き込めませんでした", fp.second.c_str());
|
||||
break;
|
||||
case eWaifu2xError_FailedProcessCaffe:
|
||||
case Waifu2x::eWaifu2xError_FailedProcessCaffe:
|
||||
sprintf(msg, "補間処理に失敗しました");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
MessageBoxA(dh, msg, "エラー", MB_OK | MB_ICONERROR);
|
||||
AddLogMessage(msg);
|
||||
|
||||
if (ret != Waifu2x::eWaifu2xError_Cancel)
|
||||
isLastError = true;
|
||||
}
|
||||
}
|
||||
@ -530,7 +568,7 @@ public:
|
||||
|
||||
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);
|
||||
else
|
||||
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::OnDialogEnd, &cDialogEvent), NULL, WM_CLOSE);
|
||||
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::Waifu2xTime, &cDialogEvent), NULL, WM_TIME_WAIFU2X);
|
||||
|
||||
// ダイアログを表示
|
||||
cDialog.DoModal(hInstance, IDD_DIALOG);
|
||||
|
@ -120,7 +120,7 @@ int main(int argc, char** argv)
|
||||
if (outputExt.length() > 0 && outputExt[0] != '.')
|
||||
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がフォルダならそのディレクトリ以下の画像ファイルを一括変換
|
||||
{
|
||||
boost::filesystem::path output_path;
|
||||
@ -227,51 +227,58 @@ int main(int argc, char** argv)
|
||||
file_paths.emplace_back(cmdInputFile.getValue(), outputFileName);
|
||||
}
|
||||
|
||||
std::vector<PathAndErrorPair> errors;
|
||||
|
||||
const eWaifu2xError ret = waifu2x(argc, argv, file_paths, cmdMode.getValue(), cmdNRLevel.getValue(), cmdScaleRatio.getValue(), cmdModelPath.getValue(), cmdProcess.getValue(), errors);
|
||||
if (ret != eWaifu2xError_OK || errors.size() > 0)
|
||||
{
|
||||
Waifu2x::eWaifu2xError ret;
|
||||
Waifu2x w;
|
||||
ret = w.init(argc, argv, cmdMode.getValue(), cmdNRLevel.getValue(), cmdScaleRatio.getValue(), cmdModelPath.getValue(), cmdProcess.getValue());
|
||||
switch (ret)
|
||||
{
|
||||
case eWaifu2xError_InvalidParameter:
|
||||
case Waifu2x::eWaifu2xError_InvalidParameter:
|
||||
printf("エラー: パラメータが不正です\n");
|
||||
break;
|
||||
case eWaifu2xError_FailedOpenModelFile:
|
||||
return 1;
|
||||
case Waifu2x::eWaifu2xError_FailedOpenModelFile:
|
||||
printf("エラー: モデルファイルが開けませんでした\n");
|
||||
break;
|
||||
case eWaifu2xError_FailedParseModelFile:
|
||||
return 1;
|
||||
case Waifu2x::eWaifu2xError_FailedParseModelFile:
|
||||
printf("エラー: モデルファイルが壊れています\n");
|
||||
break;
|
||||
case eWaifu2xError_FailedConstructModel:
|
||||
return 1;
|
||||
case Waifu2x::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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user