From 8c85eb23580e3d20a9a0c88b32d1aa4eefd7de82 Mon Sep 17 00:00:00 2001 From: lltcggie Date: Fri, 14 Oct 2016 16:47:44 +0900 Subject: [PATCH] =?UTF-8?q?=E3=82=A2=E3=83=AB=E3=83=95=E3=82=A1=E3=83=81?= =?UTF-8?q?=E3=83=A3=E3=83=B3=E3=83=8D=E3=83=AB=E3=81=8C=E5=8D=98=E8=89=B2?= =?UTF-8?q?=E3=81=AE=E5=A0=B4=E5=90=88=E3=80=81cv::INTER=5FNEAREST?= =?UTF-8?q?=E3=81=A7=E6=8B=A1=E5=A4=A7=E3=81=99=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/stImage.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++-- common/stImage.h | 4 +++ 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/common/stImage.cpp b/common/stImage.cpp index 8cc55b5..b7495cb 100644 --- a/common/stImage.cpp +++ b/common/stImage.cpp @@ -350,6 +350,7 @@ void stImage::Clear() mOrgFloatImage.release(); mTmpImageRGB.release(); mTmpImageA.release(); + mTmpImageAOneColor.release(); mEndImage.release(); } @@ -425,6 +426,34 @@ void stImage::Preprocess(const int input_plane, const int net_offset) ConvertToNetFormat(input_plane, net_offset); } +bool stImage::IsOneColor(const cv::Mat & im) +{ + assert(im.channels() == 1); + + const size_t Line = im.step1(); + const size_t Width = im.size().width; + const size_t Height = im.size().height; + + if (Width == 0 && Height == 0) + return true; + + const float *ptr = (const float *)im.data; + const float color = ptr[0]; + + for (size_t i = 0; i < Height; i++) + { + for (size_t j = 0; j < Width; j++) + { + const size_t pos = Line * i + j; + + if (ptr[pos] != color) + return false; + } + } + + return true; +} + void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset) { if (input_plane == 1) // Yモデル @@ -470,10 +499,18 @@ void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset) mTmpImageA = planes[3]; planes.resize(3); - AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる + if (!IsOneColor(mTmpImageA)) + { + AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる - // α拡大用にRGBに変換 - cv::cvtColor(mTmpImageA, mTmpImageA, CV_GRAY2RGB); + // α拡大用にRGBに変換 + cv::cvtColor(mTmpImageA, mTmpImageA, CV_GRAY2RGB); + } + else + { + mTmpImageAOneColor = mTmpImageA; + mTmpImageA.release(); + } } // BGRからRGBにする @@ -630,6 +667,21 @@ void stImage::DeconvertFromNetFormat(const int input_plane) planes.push_back(mTmpImageA); mTmpImageA.release(); + cv::merge(planes, mEndImage); + } + else if (!mTmpImageAOneColor.empty()) // 単色版Aを戻す + { + std::vector planes; + cv::split(mEndImage, planes); + + cv::Size_ zoom_size = planes[0].size(); + + // マージ先のサイズに合わせる + cv::resize(mTmpImageAOneColor, mTmpImageAOneColor, zoom_size, 0.0, 0.0, cv::INTER_NEAREST); + + planes.push_back(mTmpImageAOneColor); + mTmpImageAOneColor.release(); + cv::merge(planes, mEndImage); } } @@ -657,6 +709,16 @@ void stImage::DeconvertFromNetFormat(const int input_plane) planes.push_back(mTmpImageA); mTmpImageA.release(); } + else if (!mTmpImageAOneColor.empty()) // 単色版Aを戻す + { + cv::Size_ zoom_size = planes[0].size(); + + // マージ先のサイズに合わせる + cv::resize(mTmpImageAOneColor, mTmpImageAOneColor, zoom_size, 0.0, 0.0, cv::INTER_NEAREST); + + planes.push_back(mTmpImageAOneColor); + mTmpImageAOneColor.release(); + } // RGBからBGRにする std::swap(planes[0], planes[2]); diff --git a/common/stImage.h b/common/stImage.h index 010f616..d123b85 100644 --- a/common/stImage.h +++ b/common/stImage.h @@ -14,6 +14,7 @@ private: cv::Mat mTmpImageRGB; // RGB(あるいはY) cv::Mat mTmpImageA; // αチャンネル + cv::Mat mTmpImageAOneColor; // αチャンネル(単色の場合使われる) cv::Mat mEndImage; // 完成した画像 @@ -47,6 +48,9 @@ private: static Waifu2x::eWaifu2xError WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional &output_quality); + // im(1ch)が単色で構成されているか判定 + static bool IsOneColor(const cv::Mat &im); + void ConvertToNetFormat(const int input_plane, const int alpha_offset); Waifu2x::eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im);