cv::Mat Waifu2x::LoadMat(const boost::filesystem::path &path) { cv::Mat mat; LoadMat(mat, path); return mat; }
bool SvmClassifier::Load(const string &model_name) { // Load the normalization parameters and penalty coefficient vector<float> c; if (!LoadMat(model_name + "_normA", &normA_, &c)) { return false; } if (!LoadMat(model_name + "_normB", &normB_)) { return false; } c_ = c[0]; // Load the SVM model if (svm_model_ != NULL) { svm_free_and_destroy_model(&svm_model_); } svm_model_ = svm_load_model((model_name + FILE_EXT).c_str()); return true; }
bool HogExtractor::Load(const string &model_name) { vector<float> param; Mat tmp; if (!LoadMat(model_name + "_para", &tmp, ¶m)) { printf("Fail to load the parameter.\n"); return false; } num_orient_ = param[0]; cell_size_ = param[1]; Update(); return true; }
Waifu2x::eWaifu2xError Waifu2x::waifu2x(int factor, const uint32_t* source, uint32_t* dest, int width, int height) { Waifu2x::eWaifu2xError ret; if (!is_inited) return eWaifu2xError_NotInitialized; cv::Mat float_image; ret = LoadMat(float_image, source, width, height); if (ret != eWaifu2xError_OK) return ret; cv::Mat im; if (input_plane == 1) return eWaifu2xError_NotInitialized; else { std::vector<cv::Mat> planes; cv::split(float_image, planes); if (float_image.channels() == 4) planes.resize(3); // BGRからRGBにする //std::swap(planes[0], planes[2]); cv::merge(planes, im); } cv::Size_<int> image_size = im.size(); const bool isReconstructNoise = mode == "noise" || mode == "noise_scale" || mode == "auto_scale"; const bool isReconstructScale = mode == "scale" || mode == "noise_scale"; if (isReconstructNoise) { PaddingImage(im, im); ret = ReconstructImage(net_noise, im); if (ret != eWaifu2xError_OK) return ret; // パディングを取り払う im = im(cv::Rect(offset, offset, image_size.width, image_size.height)); } const int scale2 = ceil(log2((double)factor)); const double shrinkRatio = (double)factor / 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); if (ret != eWaifu2xError_OK) return ret; // パディングを取り払う im = im(cv::Rect(offset, offset, image_size.width, image_size.height)); } } cv::Mat process_image; if (input_plane == 1) { // 再構築した輝度画像とCreateZoomColorImage()で作成した色情報をマージして通常の画像に変換し、書き込む std::vector<cv::Mat> color_planes; CreateZoomColorImage(float_image, image_size, color_planes); float_image.release(); color_planes[0] = im; im.release(); cv::Mat converted_image; cv::merge(color_planes, converted_image); color_planes.clear(); cv::cvtColor(converted_image, process_image, ConvertInverseMode); converted_image.release(); } else { std::vector<cv::Mat> planes; cv::split(im, planes); // RGBからBGRに直す //std::swap(planes[0], planes[2]); cv::merge(planes, process_image); } 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); } // アルファチャンネルがあったら、アルファを付加してカラーからアルファの影響を抜く 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]).mul(1.0 / w2); planes[1] = (planes[1]).mul(1.0 / w2); planes[2] = (planes[2]).mul(1.0 / w2); 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(); /* ret = WriteMat(write_iamge, output_file); if (ret != eWaifu2xError_OK) return ret; write_iamge.release(); */ { const auto width = write_iamge.size().width; const auto stride = write_iamge.step1(); for (int i = 0; i < write_iamge.size().height; i++) memcpy(dest + width * i, write_iamge.data + stride * i, stride); } return eWaifu2xError_OK; }
Waifu2x::eWaifu2xError Waifu2x::waifu2x(const boost::filesystem::path &input_file, const boost::filesystem::path &output_file, const waifu2xCancelFunc cancel_func) { Waifu2x::eWaifu2xError ret; if (!is_inited) return eWaifu2xError_NotInitialized; 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" || mode == "auto_scale"; cv::Mat float_image; ret = LoadMat(float_image, input_file); if (ret != eWaifu2xError_OK) return ret; cv::Mat reconstruct_image; ret = Reconstruct(isReconstructNoise, isReconstructScale, cancel_func, float_image, reconstruct_image); if (ret != eWaifu2xError_OK) return ret; cv::Mat process_image; ret = AfterReconstructFloatMatProcess(isReconstructScale, cancel_func, float_image, reconstruct_image, process_image); if (ret != eWaifu2xError_OK) return ret; float_image.release(); const int cv_depth = DepthBitToCVDepth(output_depth); const double max_val = GetValumeMaxFromCVDepth(cv_depth); const double eps = GetEPS(cv_depth); cv::Mat write_iamge; if (output_depth != 32) // 出力がfloat形式なら変換しない process_image.convertTo(write_iamge, cv_depth, max_val, eps); else write_iamge = process_image; process_image.release(); // 完全透明のピクセルの色を消す(処理の都合上、完全透明のピクセルにも色を付けたから) // モデルによっては画像全域の完全透明の場所にごく小さい値のアルファが広がることがある。それを消すためにcv_depthへ変換してからこの処理を行うことにした // (ただしcv_depthが32の場合だと意味は無いが) if (write_iamge.channels() > 3) { std::vector<cv::Mat> planes; cv::split(write_iamge, planes); cv::Mat mask; cv::threshold(planes[3], mask, 0.0, 1.0, cv::THRESH_BINARY); // アルファチャンネルを二値化してマスクとして扱う // アルファチャンネルが0のところの色を消す planes[0] = planes[0].mul(mask); planes[1] = planes[1].mul(mask); planes[2] = planes[2].mul(mask); cv::merge(planes, write_iamge); } ret = WriteMat(write_iamge, output_file); if (ret != eWaifu2xError_OK) return ret; write_iamge.release(); return eWaifu2xError_OK; }