mirror of
https://github.com/lltcggie/waifu2x-caffe.git
synced 2025-06-26 13:42:48 +00:00
・メモリ使用量を減らすようにした
・拡大後のサイズが3GB超えていたらデータを一時ファイルに書き出してメモリ不足対策をするようにした
This commit is contained in:
parent
77b84972b3
commit
2d395ab3b1
@ -16,6 +16,7 @@
|
|||||||
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
#include <google/protobuf/io/zero_copy_stream_impl.h>
|
||||||
#include <google/protobuf/text_format.h>
|
#include <google/protobuf/text_format.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <zlib.h>
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#endif
|
#endif
|
||||||
@ -654,10 +655,9 @@ Waifu2x::eWaifu2xError Waifu2x::Zoom2xAndPaddingImage(const cv::Mat &input, cv::
|
|||||||
zoom_size.width *= 2;
|
zoom_size.width *= 2;
|
||||||
zoom_size.height *= 2;
|
zoom_size.height *= 2;
|
||||||
|
|
||||||
cv::Mat zoom_image;
|
cv::resize(input, output, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
|
||||||
cv::resize(input, zoom_image, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
|
|
||||||
|
|
||||||
return PaddingImage(zoom_image, output);
|
return PaddingImage(output, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
|
// 入力画像をzoom_sizeの大きさにcv::INTER_CUBICで拡大し、色情報のみを残す
|
||||||
@ -1618,7 +1618,7 @@ Waifu2x::eWaifu2xError Waifu2x::Reconstruct(const bool isReconstructNoise, const
|
|||||||
return eWaifu2xError_OK;
|
return eWaifu2xError_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &floatim, const cv::Mat &in, cv::Mat &out)
|
Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &floatim, cv::Mat &in, cv::Mat &out)
|
||||||
{
|
{
|
||||||
cv::Size_<int> image_size = in.size();
|
cv::Size_<int> image_size = in.size();
|
||||||
|
|
||||||
@ -1631,6 +1631,7 @@ Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isRec
|
|||||||
CreateZoomColorImage(floatim, image_size, color_planes);
|
CreateZoomColorImage(floatim, image_size, color_planes);
|
||||||
|
|
||||||
color_planes[0] = in;
|
color_planes[0] = in;
|
||||||
|
in.release();
|
||||||
|
|
||||||
cv::Mat converted_image;
|
cv::Mat converted_image;
|
||||||
cv::merge(color_planes, converted_image);
|
cv::merge(color_planes, converted_image);
|
||||||
@ -1643,6 +1644,7 @@ Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isRec
|
|||||||
{
|
{
|
||||||
std::vector<cv::Mat> planes;
|
std::vector<cv::Mat> planes;
|
||||||
cv::split(in, planes);
|
cv::split(in, planes);
|
||||||
|
in.release();
|
||||||
|
|
||||||
// RGBからBGRに直す
|
// RGBからBGRに直す
|
||||||
std::swap(planes[0], planes[2]);
|
std::swap(planes[0], planes[2]);
|
||||||
@ -1654,30 +1656,6 @@ Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isRec
|
|||||||
const int scale2 = ceil(log2(ratio));
|
const int scale2 = ceil(log2(ratio));
|
||||||
const double shrinkRatio = ratio >= 1.0 ? ratio / std::pow(2.0, (double)scale2) : ratio;
|
const double shrinkRatio = ratio >= 1.0 ? ratio / std::pow(2.0, (double)scale2) : ratio;
|
||||||
|
|
||||||
cv::Mat alpha;
|
|
||||||
if (floatim.channels() == 4)
|
|
||||||
{
|
|
||||||
std::vector<cv::Mat> planes;
|
|
||||||
cv::split(floatim, planes);
|
|
||||||
|
|
||||||
if (isReconstructScale)
|
|
||||||
Reconstruct(false, true, cancel_func, planes[3], alpha);
|
|
||||||
else
|
|
||||||
alpha = planes[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
// アルファチャンネルがあったらアルファを付加する
|
|
||||||
if (!alpha.empty())
|
|
||||||
{
|
|
||||||
std::vector<cv::Mat> planes;
|
|
||||||
cv::split(process_image, planes);
|
|
||||||
process_image.release();
|
|
||||||
|
|
||||||
planes.push_back(alpha);
|
|
||||||
|
|
||||||
cv::merge(planes, process_image);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isReconstructScale)
|
if (isReconstructScale)
|
||||||
{
|
{
|
||||||
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
|
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
|
||||||
@ -1691,6 +1669,202 @@ Waifu2x::eWaifu2xError Waifu2x::AfterReconstructFloatMatProcess(const bool isRec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Mat alpha;
|
||||||
|
if (floatim.channels() == 4)
|
||||||
|
{
|
||||||
|
std::vector<cv::Mat> planes;
|
||||||
|
cv::split(floatim, planes);
|
||||||
|
|
||||||
|
alpha = planes[3];
|
||||||
|
planes.clear();
|
||||||
|
|
||||||
|
if (isReconstructScale)
|
||||||
|
{
|
||||||
|
const auto memSize = process_image.step1() * process_image.elemSize1() * process_image.size().height;
|
||||||
|
|
||||||
|
if (memSize < 3ULL * 1000ULL * 1000ULL * 1000ULL) // 拡大後のサイズが3GB超えていたらファイルに書き出してメモリ不足対策
|
||||||
|
Reconstruct(false, true, cancel_func, alpha, alpha);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::filesystem::path temp = boost::filesystem::unique_path("%%%%-%%%%-%%%%-%%%%.bin");
|
||||||
|
|
||||||
|
auto compp = [](const cv::Mat &im, const boost::filesystem::path &temp)
|
||||||
|
{
|
||||||
|
static char outbuf[10240000];
|
||||||
|
FILE *fout;
|
||||||
|
z_stream z;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if (!(fout = fopen(temp.string().c_str(), "wb")))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
z.zalloc = Z_NULL;
|
||||||
|
z.zfree = Z_NULL;
|
||||||
|
z.opaque = Z_NULL;
|
||||||
|
|
||||||
|
if (deflateInit(&z, Z_DEFAULT_COMPRESSION) != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
z.next_in = (z_const Bytef *)im.data;
|
||||||
|
z.avail_in = im.step1() * im.elemSize1() * im.size().height;
|
||||||
|
z.next_out = (Bytef *)outbuf;
|
||||||
|
z.avail_out = sizeof(outbuf);
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
const int status = deflate(&z, Z_FINISH);
|
||||||
|
if (status == Z_STREAM_END)
|
||||||
|
break; // 完了
|
||||||
|
|
||||||
|
if (status != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z.avail_out == 0)
|
||||||
|
{
|
||||||
|
if (fwrite(outbuf, 1, sizeof(outbuf), fout) != sizeof(outbuf))
|
||||||
|
{
|
||||||
|
fclose(fout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
z.next_out = (Bytef *)outbuf; // 出力バッファ残量を元に戻す
|
||||||
|
z.avail_out = sizeof(outbuf); // 出力ポインタを元に戻す
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 残りを吐き出す
|
||||||
|
if ((count = sizeof(outbuf) - z.avail_out) != 0)
|
||||||
|
{
|
||||||
|
if (fwrite(outbuf, 1, count, fout) != count)
|
||||||
|
{
|
||||||
|
fclose(fout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 後始末
|
||||||
|
if (deflateEnd(&z) != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fout);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fout);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto decompp = [](const cv::Size &size, const int type, cv::Mat &out, const boost::filesystem::path &temp)
|
||||||
|
{
|
||||||
|
static char inbuf[102400];
|
||||||
|
FILE *fin;
|
||||||
|
z_stream z;
|
||||||
|
|
||||||
|
if (!(fin = fopen(temp.string().c_str(), "rb")))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
z.zalloc = Z_NULL;
|
||||||
|
z.zfree = Z_NULL;
|
||||||
|
z.opaque = Z_NULL;
|
||||||
|
|
||||||
|
z.next_in = Z_NULL;
|
||||||
|
z.avail_in = 0;
|
||||||
|
if (inflateInit(&z) != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
out = cv::Mat(size, type);
|
||||||
|
|
||||||
|
const int MaxSize = out.step1() * out.elemSize1() * out.size().height;
|
||||||
|
z.next_out = (Bytef *)out.data; // 出力ポインタ
|
||||||
|
z.avail_out = MaxSize; // 出力バッファ残量
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
if (z.avail_in == 0)
|
||||||
|
{
|
||||||
|
z.next_in = (Bytef *)inbuf;
|
||||||
|
z.avail_in = fread(inbuf, 1, sizeof(inbuf), fin);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int status = inflate(&z, Z_NO_FLUSH);
|
||||||
|
if (status == Z_STREAM_END)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (status != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z.avail_out == 0)
|
||||||
|
{
|
||||||
|
fclose(fin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inflateEnd(&z) != Z_OK)
|
||||||
|
{
|
||||||
|
fclose(fin);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fin);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto step1Old = process_image.step1();
|
||||||
|
const auto size = process_image.size();
|
||||||
|
const auto type = process_image.type();
|
||||||
|
compp(process_image, temp);
|
||||||
|
process_image.release();
|
||||||
|
|
||||||
|
Reconstruct(false, true, cancel_func, alpha, alpha);
|
||||||
|
|
||||||
|
decompp(size, type, process_image, temp);
|
||||||
|
boost::filesystem::remove(temp);
|
||||||
|
|
||||||
|
assert(step1Old == process_image.step1());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isReconstructScale)
|
||||||
|
{
|
||||||
|
const cv::Size_<int> ns(image_size.width * shrinkRatio, image_size.height * shrinkRatio);
|
||||||
|
if (image_size.width != ns.width || image_size.height != ns.height)
|
||||||
|
{
|
||||||
|
int argo = cv::INTER_CUBIC;
|
||||||
|
if (ratio < 0.5)
|
||||||
|
argo = cv::INTER_AREA;
|
||||||
|
|
||||||
|
if (!alpha.empty())
|
||||||
|
cv::resize(alpha, alpha, ns, 0.0, 0.0, argo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// アルファチャンネルがあったらアルファを付加する
|
||||||
|
if (!alpha.empty())
|
||||||
|
{
|
||||||
|
std::vector<cv::Mat> planes;
|
||||||
|
cv::split(process_image, planes);
|
||||||
|
process_image.release();
|
||||||
|
|
||||||
|
planes.push_back(alpha);
|
||||||
|
alpha.release();
|
||||||
|
|
||||||
|
cv::merge(planes, process_image);
|
||||||
|
}
|
||||||
|
|
||||||
// 値を0~1にクリッピング
|
// 値を0~1にクリッピング
|
||||||
cv::threshold(process_image, process_image, 1.0, 1.0, cv::THRESH_TRUNC);
|
cv::threshold(process_image, process_image, 1.0, 1.0, cv::THRESH_TRUNC);
|
||||||
cv::threshold(process_image, process_image, 0.0, 0.0, cv::THRESH_TOZERO);
|
cv::threshold(process_image, process_image, 0.0, 0.0, cv::THRESH_TOZERO);
|
||||||
|
@ -133,7 +133,7 @@ private:
|
|||||||
eWaifu2xError BeforeReconstructFloatMatProcess(const cv::Mat &in, cv::Mat &out, bool &convertBGRflag);
|
eWaifu2xError BeforeReconstructFloatMatProcess(const cv::Mat &in, cv::Mat &out, bool &convertBGRflag);
|
||||||
eWaifu2xError ReconstructFloatMat(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
eWaifu2xError ReconstructFloatMat(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
||||||
eWaifu2xError Reconstruct(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
eWaifu2xError Reconstruct(const bool isReconstructNoise, const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &in, cv::Mat &out);
|
||||||
eWaifu2xError AfterReconstructFloatMatProcess(const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &floatim, const cv::Mat &in, cv::Mat &out);
|
eWaifu2xError AfterReconstructFloatMatProcess(const bool isReconstructScale, const waifu2xCancelFunc cancel_func, const cv::Mat &floatim, cv::Mat &in, cv::Mat &out);
|
||||||
|
|
||||||
eWaifu2xError waifu2xConvetedMat(const bool isJpeg, const cv::Mat &inMat, cv::Mat &outMat,
|
eWaifu2xError waifu2xConvetedMat(const bool isJpeg, const cv::Mat &inMat, cv::Mat &outMat,
|
||||||
const waifu2xCancelFunc cancel_func = nullptr);
|
const waifu2xCancelFunc cancel_func = nullptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user